Mysql 事务
什么是事务
不可分割的操作,比如一个事务要修改 A 表和删除 B 表的数据两个操作,这两个操作都成功,这个事务才 commit,不然 rollback
每条 SQL 语句都是一个事务
只对 DML 生效
CAID
一致性(Consistency):让数据保持一定程度的合理性,比如用户加入购物车,购物车数量 +1,库存就 -1
原子性(Atommicity):事务所包含的操作要么全部成功,要么全部失败
隔离性(Isolation):事务与事务之间的隔离,比如一个事务在操作 id 是 1001 的数据,要等这个事务结束了别的事务才能操作这条数据,这种机制是 Mysql 默认的,
可以修改,下面会说
持久性(Durability):事务一旦提交,就不能再更改了(再发起一个事务能操作数据,但是和之前的事务是没关系的)
使用事务
开启事务:begin transaction 或 start transaction;
回滚事务:rollback;
提交事务:commit;
注:Mysql 默认开启事务
事务并发问题
脏读:
获取了未提交数据
产生场景:A 事务更新了数据,还未提交,此时 B 事务获取了更新的数据,然后 A 事务回滚了,导致 B 事务获取的数据不准确
解决办法:事务隔离级别设置成 RED COMMITTED
不可重复读:
一个事务两次查询的结果不一样(针对数据,是数据不一样,因 update 引发)
产生场景:A 事务获取了数据,B 事务修改了数据并提交,A 事务再次获取,就得到了与上一次不一样的数据
解决办法:事务隔离级别设置成 REPEATABLE READ
幻读:
一个事务两次相同条件查询的结果集行数不一致(针对总条数,因 insert 或 delete 引发)
产生场景:A 事务获取了总条数, B 事务新增了几条数据并提交,A 事务再次获取总条数,就得到了与上一次不一样的总条数
解决办法:事务隔离级别设置成 SERIALIZABLE
事务的隔离级别
读未提交(READ UNCOMMITTED):一个事务可以读取别的事务未提交的数据
读提交(RED COMMITTED):一个事务必须等别的事务提交才能读取
可重复读(REPEATABLE READ):Mysql 默认事务隔离级别
串行化(SERIALIZABLE):最安全,但是效率低下,比较耗数据库性能,一般不使用
查看事务的隔离级别
SELECT @@global.tx_isolation,@@tx_isolation;
设置事务的隔离级别
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;
隔离级别和并发问题对应关系
事务隔离级别 | 脏读 | 可重复读 | 幻读 |
读未提交(READ UNCOMMITTED) | 是 | 是 | 是 |
读提交(RED COMMITTED) | 否 | 是 | 是 |
可重复读(REPEATABLE READ) | 否 | 否 | 是 |
串行化(SERIALIZABLE) | 否 | 否 | 否 |