写点什么

spring 大事务

用户头像
Rubble
关注
发布于: 3 小时前
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 查询


select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>10
复制代码

如何避免大事务

  • 非必要不需要手动开启事务即添加 @Trancational 注解。如 select 操作,不要回滚的 crud 操作,单条语句 mysql 本身存在事务。

  • 在一个事务里面, 避免一次处理太多数据

  • 在一个事务里面,尽量避免不必要的查询

  • 在一个事务里面, 避免耗时太多的操作,造成事务超时。一些非 DB 的操作,比如 rpc 调用,消息队列的操作尽量放到事务之外操作

  • 在一个事务里面,尽量避免复杂的计算


对复杂的耗时较长的业务,在逻辑处理层不要开启事务,进行数据查询,逻辑处理,组装要进行 db 操作的数据,最后再在 dbservice 层开启事务,以减少事务持续的时间。


优化 for 循环的处理,如多次 rpc 的调用,改为单次批量调用。


对于数据库批量操作,控制批次最大提交量,不要在同一事务中多批次提交。


提供一个大事务导致连接池占满的监控图,请求链接的耗时 Acquire time 飙升。



用户头像

Rubble

关注

还未添加个人签名 2021.06.01 加入

还未添加个人简介

评论

发布
暂无评论
spring 大事务