1.事务
事务是数据库操作的基本单位,只有Mysql使用innodb引擎才能使用事务;
2.事务的基本特性
原子性A:一个事务中的线程要么全部执行,要么全部不执行 ;
隔离性I:事务之间相互不干扰;
一致性C:数据库执行执行前是一个状态,执行后是另外一个状态;
持久性D:事务执行后无法回滚;
3.事务的隔离级别
未提交读:脏读现象,事务A读取到事务B未提交的数据;
已提交读:不可重复读现象,解决了脏读现象,在同一个事务里面进行两次Select操作,先读取一遍,然后另外一个事务对你读取的数据进行update操作,所以前后两次读取的是两个不同的数据;
可重复读:解决不可重复度现象,幻读现象,事务Aupdate数据库之后得到的数据,事务BInsert了数据库,增加了许多符合事务A查询条件的数据,事务A再次进行读取的时候能读取到符合自己update条件却位update的数据;
串行化:解决所有问题,进行数据操作是不允许其他事务进行对这个数据的任何操作,sync锁;
4.可重复读的实现原理(可重复读也已经解决的幻读问题)
未提交读是性能最好的隔离级别,因为他一点锁都没用,所以他的安全性是最差的。而串行化是全部加锁,读取的时候加读锁禁止其他事务进行更新操作,update的时候加排他锁,因为都加锁所以他的性能是最差的。
MySql默认的事务隔离级别就是可重复读,Oracle的默认事务隔离级别是已提交读。
可重复读是靠MVVC(多版本并发控制)来实现的。
为每个事务颁发版本号,如果是写操作则版本号进行自增,我理解的就是写事务相当于是一个版本补丁,当进行一个写事务版本自然而然的就会增加。
当你进行读的时候就会生成当前的快照 也就是一致性视图,读取的规则就是
1.当前事务的写操作可以读取
2.版本号小于当前版本号的写事务可以读取
3.未提交的写操作不能读取
4.在获取快照之后的写操作也无法读取
已提交读是在每次语句执行的时候生成快照
5.并发的写问题
行锁和表锁
如果能具体到行就进行行锁,如果无法具体到行就进行表锁(如果使用主键就能定位到具体的行)
6.可重复读如何解决的幻读问题
解决并发写问题使用的是行锁和表锁,解决可重复读问题的也是锁分别是行锁和间隙锁。
首先知道MySql维护了一个B+树来维护索引,而且B+树的索引是有序的。
首先是表,此时的age已经被设置成了索引
B+树中索引的样子,同时索引被分成了几个区间
下面是演示过程
此时加上的间隙锁是(负无穷,10]和(10, 30],同时还有10的行锁,这样就解决的幻读问题,当然你如果插入的是大于30的数据也是可以的
上述情况是存在索引的情况,如果没有索引还是使用的表锁,直接将整个表上锁,不允许其他的事务进行更改。
总结
事务是数据库的基础,他们的实现原理更是基础中的基础,继续学吧