数据库事务
1、事务的定义
事务是由一组SQL语句语句组成的逻辑处理单元。
2、事务的ACID
- 原子性(Atomicity):
一个事务(transaction)的所有操作,要么全部完成,要么全部不完成,不会出现成功一半的情况
- 一致性(Consistency):
在事务开始和完成时,数据库中的数据都保持一致的状态,事务开始和结束之间的中间状态不会被其他事务看到
- 隔离性(Isolation):
一个事务的执行不能被其他事务干扰
- 持久性(Durability):
一个事务一旦提交,改变是永久性的,不会被回滚
3、事务的实现:
事务的隔离性由锁机制实现,原子性、一致性和持久性由事务的redo 日志和undo 日志来保证
4、并发事务带来的问题
- 第一类更新丢失:A事务撤销时,把已提交的B事务的数据覆盖掉
- 第二类更新丢失:A事务提交时,把已提交的B事务的数据覆盖掉
- 脏读:A事务对一数据进行了修改,但尚未提交,B事务读取了A事物修改但未提交的数据。A事务发生异常,回滚了数据,那么此时B事务读取的数据就是脏数据
- 不可重复读:A事务内,多次读写同一数据,在A事务并没有结束,B事务对这数据进行了修改,那么A事务两次读取的数据可能就不一样的,这样就发生了同一事务内两次相同的查询读到的数据不一样。
- 幻读:不可重复读的重点是修改,幻读的重点在于新增或者修改,即在一个事物内读取出来的记录数不一样
避免以上问题的发生,最常用的就是锁技术,常见的锁如乐观锁、悲观锁
以下图片和解释来自于其它博主,故贴出原博客地址: https://www.cnblogs.com/takumicx/p/9998844.html
- 脏写
脏写是指事务回滚了其他事务对数据项的已提交修改,比如下面这种情况
在事务1对数据A的回滚,导致事务2对A的已提交修改也被回滚了。
- 丢失更新
丢失更新是指事务覆盖了其他事务对数据的已提交修改,导致这些修改好像丢失了一样。
事务1和事务2读取A的值都为10,事务2先将A加上10并提交修改,之后事务2将A减少10并提交修改,A的值最后为,导致事务2对A的修改好像丢失了一样
- 脏读
脏读是指一个事务读取了另一个事务未提交的数据
在事务1对A的处理过程中,事务2读取了A的值,但之后事务1回滚,导致事务2读取的A是未提交的脏数据。
- 不可重复读
不可重复读是指一个事务对同一数据的读取结果前后不一致。脏读和不可重复读的区别在于:前者读取的是事务未提交的脏数据,后者读取的是事务已经提交的数据,只不过因为数据被其他事务修改过导致前后两次读取的结果不一样,比如下面这种情况
由于事务2对A的已提交修改,事务1前后两次读取的结果不一致。
- 幻读
事务1查询A<5的数据,由于事务2插入了一条A=4的数据,导致事务1两次查询得到的结果不一样
5、MYSQL事务的隔离级别
- Read uncommitted (读未提交):
允许事务读取未被其他事务提交的变更,可能出现脏读,不可重复读和幻读问题
- Read committed (读已提交):
允许事务读取已经被其他事务提交的变更,可以避免脏读,可能有不可重复读和幻读的问题
- Repeatable read (可重复读 MYSQL默认隔离级别):
确保事务可以从一个字段中读取到相同的值,在这个事务持续期间,禁止其他事务对着这字段进行更新,可以避免脏读和不可重复读,可能有幻读
- Serializable (串行化):
所有事务一个接一个地串行执行,可以避免脏读、不可重复读、幻读
参考链接:
https://www.zhihu.com/question/31346392
https://www.cnblogs.com/takumicx/p/9998844.html