事务的概念:我们把需要保证原子性、隔离性、一致性和持久性的一个或多个数据库操作称之为一个事务。
场景:小明向小强转账10元
1.1.1 原子性(Atomicity)转账操作是一个不可分割的操作,要么转失败,要么转成功,不能存在中间的状态,也就是转了一半的这种情况。我们把这种要么全做,要么全不做的规则称之为原子性。
1.1.2 一致性(Consistency)对于上面的转账场景,一致性表示每一次转账完成后,都需要保证整个系统的余额等于所有账户的收入减去所有账户的支出。
如果不遵循原子性,也就是如果小明向小强转账10元,但是只转了一半,小明账户少了10元,小强账户并没有增加,所以没有满足一致性了。同样,如果不满足隔离性,也有可能导致破坏一致性。
所以说,数据库某些操作的原子性和隔离性都是保证一致性的一种手段,在操作执行完成后保证符合所有既定的约束则是一种结果。
实际上我们也可以对表建立约束来保证一致性。
1.1.3 隔离性(Isolation)另外一个场景:
1.小明向小强转账10元
2.小明向小红转账10元
隔离性表示上面两个操作是不能相互影响的。
1.1.4 持久性(Durability)对于转账的交易记录,需要永久保存。
1.2 事务的使用 1.2.1 开启事务begin [work]
start transaction
这里需要强调一下,ROLLBACK语句是我们程序员手动的去回滚事务时才去使用的,如果事务在执行过程中遇到了某些错误而无法继续执行的话,事务自身会自动的回滚。
1.2.4 自动提交如果你开启了一个事务,并且已经敲了很多语句,忽然发现上一条语句有点问题,你只好使用ROLLBACK语句来让数据库状态恢复到事务执行之前的样子,然后一切从头再来,总有一种一夜回到解放前的感觉。
所以,MYSQL提出了一个保存点(英文;savepoint)的概念,就是在事务对应的数据库语句中打几个点,我们在调用ROLLBACK语句时可以指定会滚到哪个点,而不是回到最初的原点。
定义保存点的语法如下:
一个事务可以读到其他事务还没有提交的数据,会出现脏读。
一个事务读到了另一个未提交事务修改过的数据,这就是脏读。
左边事务,把c更改为7以后,右边事务直接查出,进行后续业务操作了。但是,后面左边事务又把它改为了8,右边事务就相当于读到了脏的数据。
1.3.2 读已提交(Read committed)一个事务只能读到另一个已经提交的事务修改过的数据,并且其他事务每对该数据进行一次修改并提交后,该事务都能查询得到最新值,会出现不可重复读、幻读。
如果一个事务先根据某些条件查询出一些记录,之后另一个事务又向表中插入了符合这些条件的记录,原先的事务再次按照该条件查询时,能把另—个事务插入的记录也读出来,这就是幻读。
1.不可重复读
2.幻读
一个事务第一次读过某条记录后,即使其他事务修改了该记录的值并且提交,该事务之后再读该条记录时,读到的仍是第一次读到的值,而不是每次都读到不同的数据,这就是可重复读,这种隔离级别解决了不可重复,但是还是会出现幻读。
MySQL默认隔离级别就是可重复读。
以上3种隔离级别都允许对同一条记录同时进行读-读、读·写、写-读的并发操作,如果我们不允许读-写、写-读的并发操作,可以使用SERIALIZABLE隔离级别,这种隔离级别因为对同一条记录的操作都是串行的,所以不会出现脏读、幻读等现象。
1.3.5 总结每次读取数据前都生成一个ReadView
在第一次读取数据时生成一个ReadView
参考,视频教程,参考博客