spring 大事务
什么是大事务
耗时比较长的事务称之为大事务
spring 中开启 @Trancational 注解开启事务或者 AOP 切面开启事务。不手动开启事务,mysql 默认自动提交事务,一条语句执行完自动提交。
慢 sql,执行一条 sql 的时间超过设定值即慢 sql。慢 sql 记录在慢 sql 日志中,log_slow_queries= "C:/temp/mysql_slow.log"。系统中一般会对慢 sql 进行监控,对高频影响性能的慢 sql 进行优化处理。
大事务产生的原因
操作的数据比较多
大量的锁竞争
事务中有其他非 DB 的耗时操作
运算量比较大
常见的形式有 select 较多,调用了 rpc 方法较多,for 循环处理数据较多,执行了比较耗时的计算,执行了较大的 batch 数据库操作。
大事务造成的影响
并发情况下,数据库连接池容易被撑爆
锁定太多的数据,造成大量的阻塞和锁超时
执行时间长,容易造成主从延迟
回滚所需要的时间比较长
undo log 膨胀
最主要的影响数据库连接池容易被撑爆,导致大量线程等待,造成请求无响应或请求超时。
从监控维度来看 qps 基于之前无太大变化,jvm 数据指标正常,但数据库连接已占满,存在大量等待线程。
如何查询大事务
sql 查询
如何避免大事务
非必要不需要手动开启事务即添加 @Trancational 注解。如 select 操作,不要回滚的 crud 操作,单条语句 mysql 本身存在事务。
在一个事务里面, 避免一次处理太多数据
在一个事务里面,尽量避免不必要的查询
在一个事务里面, 避免耗时太多的操作,造成事务超时。一些非 DB 的操作,比如 rpc 调用,消息队列的操作尽量放到事务之外操作
在一个事务里面,尽量避免复杂的计算
对复杂的耗时较长的业务,在逻辑处理层不要开启事务,进行数据查询,逻辑处理,组装要进行 db 操作的数据,最后再在 dbservice 层开启事务,以减少事务持续的时间。
优化 for 循环的处理,如多次 rpc 的调用,改为单次批量调用。
对于数据库批量操作,控制批次最大提交量,不要在同一事务中多批次提交。
提供一个大事务导致连接池占满的监控图,请求链接的耗时 Acquire time 飙升。
评论