前言
TCL(Transaction Control Langage,事务性语言),控制事务来实现ACID,即事务的基本特性。
本文从读写的角度,将事务并发和隔离级别串起来。
一、TCL
1、从读写来理解事务并发问题
一、TCL事务控制语言
含义)一个或一组SQL语句组成一个执行单元,要么全部执行完,要么都不执行。
作用)保证操纵数据的正确性。
例子)
我给他转500,我的钱少500
意外
他收500,他的钱增500
二、存储引擎
含义)数据的存储技术
查看当前引擎)show ENGINES;
特性)ACID
1)原子性(Atomicity),事务里面的语句不可分割,要么一起成功,要么一起失败。
2)一致性(Consistency),一个一致性状态,变成另一个一致性状态。
3)隔离性(Isolation),并发情况下,各个事务不能相互干扰。
4)持久性(Durability),事务一旦提交,就是对数据的永久性改变,接下来的其它操作已经不能影响上一个事务了,即不能让上一个事务回滚。
三、事务的创建
- 隐式的事务
事务没有明显的开启和结束,如insert、update、delete.- 显示的事务
含义) 事务明显的开启和结束,且必须设置自动提交功能为禁用,保证持久性。
语法)set autocommit = 0
步骤)
1)开启事务,set autocommit = 0;START TRANSACTION[可选]
2)sql
3)结束事务commit | rollback;
SAVEPOINT) 搭配rollback,设置一个回滚点,然后rollback到回滚点。
SAVEPOINT语法)sql1; savepoint a; sql2; ROLLBACK a;
SAVEPOINT含义)回滚到a处,只撤销SQL2的执行。
四、事务并发
含义)多个事务访问数据库中相同的数据
三种问题)
1)脏读,T2 读了T1 更新但未提交的数据,这是一个临时无效的数据。
解释:一个事务读,另一个事务读写+rollback,这种情况一般需避免,对于影响自己只读问题不大,但是读到了别人在事务中修改的数据不太好,即使rollback还是会泄漏信息。如店老板插入了3000条商品,可是他发现今天没有做活动,可以rollback,但是也被别人读到了,即泄漏了信息。
2)不可重复读,就是再次读的数据不一样。
解释:一个事务读,另一个事务读写+commit,这种情况一般都能接受,即处理好脏读数据即可。这种情况是只能读到别人commit之后的数据,虽然前后数据变了,但是对于只读影响却不大,反正读的是旧数据又不是脏数据,重读一次就好了,对应于刷新以下就有了。如今天是活动日,我很积极提前就去看,发现没有活动商品,到点了店老板去插入活动商品,然后commit。我再刷新一下就读到了新数据,新旧数据不一样,但无所谓。
3)幻读,T1 T2 读到同样的数据,T2 对该数据做了修改并commit,T1读到的数据保持原来的旧数据即可重复读,但是T1再对该字段修改用的是T2更新后的新数据,而不是旧数据,出现了前后数据不一致,称其为幻读。
解释:两个事务都读写的情况,这里的写为增删改。这里也是前后数据不一样,但是这是有写操作的情况,对于这种要分情况来决定是否设置串行化隔离级别还是不用管。在repeatable read情况下,这里的修改会加锁,每次修改的是别的事务修改并提交之后的数据,如别的事务修改未提交,该事务想修改就必修等待。而在serializable隔离级别下,当一个事务读了,就会加读锁,其它事务只能读,而修改就必须等待加读锁的事务commit。了解里面实现的原理,就要分具体的增删改情况来看是会出现问题来进行隔离。
避免问题)通过隔离级别来控制事务并发带来的问题。
原理)通过加读写锁。图见下。
五、辅助操作
- 查看隔离级别
select @@tx_isolation;
- 设置隔离级别
set session transaction isolation level read uncommitted;
六、delete 与truncate在事务使用时的区别
- 能否回滚
delete能,truncate不能。
2、加读写锁来隔离事务
1)事务的隔离级别
注:
1.可以看成就是通过加读写锁来控制这三个事务并发问题。
2.MySQL默认隔离级别Repeateable read.
总结
1)并发事务带来的问题,问题的源头是同时的读写。
2)问题的解决,原理是为读写加锁。
参考文献
[1] 数据库萨师煊第五版
[2] MySQL 尚硅谷