[MySQL] mysql的事务隔离和幻读和死锁问题
1.系统要通过严格的ACID测试,ACID表示原子性/一致性/隔离性/持久性
原子性:一个事务必须被视为一个不可分割的最小工作单元
一致性:数据库总是从一个一致性的状态转换到另外一个一致性的状态
隔离性:通常来说一个事务所做的修改在最终提交以前对其他事务是不可见的
持久性:一旦事务提交,则其所做的修改就会永久保存到数据库中
2.sql标准中定义了四种隔离,较低级别的隔离可以执行更高的并发,开销也更低
READ UNCOMMITTED 未提交读,事务中的修改还没提交,其他事务就可以看到,这也是脏读,一般不会用
READ COMMITED 提交读,大多数的默认级别,在提交之前,所做的任何修改对其他事务都是不可见的
REPEATABLE READ 可重复读,解决了脏读的问题,保证了同一个事务中多次读取同一个记录结果一致,但是还是会有幻读问题
SERIALIZABLE 可串行化,避免幻读问题,每一行都加锁
3.事务的隔离级别下的问题
脏读:事务可以读取别的事务未提交的脏数据
不可重复读:事务不可以读取未提交的数据,但是如果在另一个事务修改并提交了数据,此时可以读取到,同一事务两次相同的select结果可能会不同
幻读:事务不可以读取未提交的,也不能读取修改提交的,但是当另一个事务插入新数据提交后,我本次事务有时会插入冲突,或者更新时更新的数据多了
加锁:强制串行执行,锁开销比较大
4.查看隔离级别:
select @@global.tx_isolation, @@tx_isolation;
| @@global.tx_isolation | @@tx_isolation |
+-----------------------+-----------------+
| REPEATABLE-READ | REPEATABLE-READ
5.幻读问题
开启事务,查询数据
此时有另外的会话插入新数据
再次查询新数据不会出现,但是插入时会报错
6.mysql 死锁:
1.两个或多个事务在同一个资源上相互占用,并请求锁定对方占用的资源,导致恶性循环
2.解决这种问题,检测到死锁的循环依赖,立即返回一个错误
3.时间达到了锁等待超时限定,放弃锁请求
4.将持有最少行级写锁的事务回滚
5.如果是真正的数据冲突,这种是很难避免的,必须要提交或回滚其中一个事务
开启事务,更新数据,还没提交
此时另外的会话执行同样的更新,会阻塞,一段时间和会报错
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction