MySql事务原理与优化建议
- 前言
- 一、事务的定义
- 二、事务的ACID特性
- 三、事务的隔离性
- 四、读写锁
- 五、MVCC机制
- 六、事务提交的流程
- 七、大事务的影响
- 八、事务优化建议
- 总结
前言
最新的 Java 面试题,技术栈涉及 Java 基础、集合、多线程、Mysql、分布式、Spring全家桶、MyBatis、Dubbo、缓存、消息队列、Linux…等等,会持续更新。
如果对老铁有帮助,帮忙免费点个赞,谢谢你的发财手!
一、事务的定义
- 事务:就是一组操作要么全部成功,要么全部失败回滚,目的就是为了保证数据的一致性。
二、事务的ACID特性
- 1、原子性(Atomicity):当前事务的操作要么全部成功,要么全部同时失败。
- 它是由undo log日志来实现。
- 2、一致性(Consistency):事务前后的数据是一致的。
- 它是由其他三个特性来保证的。
- 3、隔离性(Isolation):事务之间互相不影响。
- 它是由mysql的各种锁以及,MCCC机制来实现的。
- 4、永久性(Durability):事务一旦提交成功,对数据的修改就是永久性的。
- 它是由redo log 来实现的。
三、事务的隔离性
- 在mysql中的InnoDB引擎中,定义了四种隔离级别,隔离级别越高,性能越差。
- 1、read uncommit(读未提交):会产生脏读
- 2、read commit(读已提交):不可重复读
- 3、repeatable read(可重复读):会产生幻读
- 4、serializable(串行读):性能最差
四、读写锁
- 读锁(共享锁、S锁):select …lock in share mode;
读锁是共享的,多个事务可以同时读取同一个资源,但不允许其他事务修改。
- 写锁(独占锁、X锁):select …for update;
写锁是排他的,会阻塞其他的写锁或读锁,insert 、delete、update都会加写锁。
五、MVCC机制
- MVCC(multi-version Concurrency Control)多版本并发控制,可以做到读写不阻塞,避免了类似脏读这样的问题,主要通过undo日志链来实现。
- select操作是快照读(历史版本)
- insert、delete和update是当前读(当前版本)
- read commit(读已提交),语句级快照
- repeatable rea(可重复读),事务级快照
六、事务提交的流程
- 1、client执行一条SQL,会经过连接器(管理连接和权限校验),分析器(词法语法分析),优化器(执行计划生成索引选择),执行器(调用引擎接口);
- 2、从磁盘中加载复合条件的数据到内存中(Buffer pool),数据库的增删改查都是直接操作Buffer pool的;
- 3、写入更新数据的旧值到undo log中,如果事务失败回滚,需要用到undo log日志里的数据恢复Buffer pool里的缓存数据;
- 4、更新Buffer pool里的数据,同时记录redo log日志顺序写入到磁盘,此时还是处于prepare状态;
- 5、准备提交事务,记录bin log 日志写入到磁盘,主要是用来恢复数据库磁盘的数据;
- 6、提交事务,同时把redo log日志的标记改为commit状态;
- 7、操作系统会把Buffer pool中的数据,以page为单位写入到磁盘中。
如果事务提交成功,Buffer pool里的数据还没来得及写入到磁盘,系统宕机了,可以用redo log日志里的数据来恢复磁盘ibd文件里的数据。
七、大事务的影响
- 并发情况下,数据库连接池容易撑爆;
- 锁定太多的数据,造成大量的阻塞和锁超时;
- 执行时间长,容易造成主从延迟;
- 回滚所需要的时间比较长;
- 容易导致死锁。
八、事务优化建议
- 将查询等数据准备操作放到事务外;
- 事务中避免远程调用,远程调用要设置超时,防止事务等待时间过久;
- 事务中避免一次性处理太多的数据,可以拆分成多个事务分次处理;
- 封信等设计加锁的操作尽可能放在事务靠后的为准;
- 能异步处理的尽量异步处理。
总结
都已经看到这里啦,赶紧收藏起来,祝您工作顺心,生活愉快!