MySQL事务原理
在MySQL中并发执行多个事务,如果对同一批数据进行修改操作,就会导致出现脏写,脏读,不可重复读,幻读这些问题。
事务具有以下四个属性,简称ACID
原子性(Atomicity):当前失误的操作要么同时成功,要么同时失败。原子性由undo log日志来实现
一致性(Consistent):使用事务的最终目的,由其他3个特性以及业务代码正确的逻辑实现
隔离性(lsolation):在事务病房执行时,他们内部的操作不能互相干扰。隔离性由MySQL的各种锁以及MVCC机制来实现。
持久性(Durable):一旦提交了事务,他对数据库的改变就应该是永久性的。持久性由redo og日志来实现的。
脏写
当两个或多个事务选择同一行数据修改,有可能发生更新数据丢失,即最后的更新覆盖了由其他事务所做的更新。
脏读
事务A读取到了事务B已经修改但尚未提交的数据
不可重复读
事务A内部的相同查询语句在不同时刻读取的结果不一致
幻读
事务A读取到了事务B提交的更新数据
在隔离性中,对于事务的隔离级别及其对应产生的问题如下
其中MySQL默认的事务隔离级别为可重复读。
- 大事务的影响 并发的情况下,数据库连接池容易被撑爆
- 锁定的数据太多,造成大量的阻塞和锁超时
- 执行的时间长,容易造成主从延时
- 回滚需要的时间长
- undo log容易膨胀
- 容易导致死锁
优化方案
- 将查询等数据准备操作放到事务外;
- 事务中避免远程调用,远程调用要设置超时
- 避免一次性处理的数据太多,进行拆分
- 更新等涉及到加锁的操作可以放到最后
- 能异步处理可以异步