前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >REQUIRES_NEW导致数据库连接死锁

REQUIRES_NEW导致数据库连接死锁

作者头像
十毛
发布2019-07-18 15:03:59
3.3K0
发布2019-07-18 15:03:59
举报

在项目中,我们使用Spring事务传播类型REQUIRES_NEW实现了子事务的独立性,但是在高并发的情况下出现了数据库连接获取不到的问题

问题症状

当出现较大并发访问系统时,比如30并发,则会出现以下错误

CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is java.sql.SQLTransientConnectionException: HikariPool1 - Connection is not available, request timed out after 30000ms.

获取数据库连接的时间居然超过了30秒,正常情况下一个请求的处理时间是200ms,所以觉得特别奇怪。 按说即使数据库连接数小于请求并发数,因为数据库连接是共享的,请求也可以很快地获取到数据库连接并完成请求。但是实际却超过了30秒。

查看连接池情况

  • 从连接池信息可以看出,当请求并发量很大时,连接数确实不够。而且最大连接数已经是100(默认是10)
HikariPool1 - Before cleanup stats (total=22, active=0, idle=22, waiting=0)
HikariPool1 - Before cleanup stats (total=49, active=49, idle=0, waiting=87)
oikariPool1 - Before cleanup stats (total=100, active=100, idle=0, waiting=70)
HikariPool1 - Before cleanup stats (total=100, active=0, idle=100, waiting=0)
HikariPool1 - Before cleanup stats (total=100, active=0, idle=100, waiting=0)

查看日志,觉得更加奇怪了,请求并发数是30,连接数已经是100了,但是还是不够。 所以怀疑连接泄漏了。但是使用的Spring Boot来管理连接池,并不是手动使用连接池,应该不可能是泄漏了。

查看请求日志

  • 查看一个请求中数据库连接相关的日志
Acquired Connection [HikariProxyConnection@880338874 wrapping com.mysql.cj.jdbc.ConnectionImpl@332c8129] for JDBC transaction
Switching JDBC Connection [HikariProxyConnection@880338874 wrapping com.mysql.cj.jdbc.ConnectionImpl@332c8129] to manual commit
...
Transaction synchronization suspending SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@726cda03]
Acquired Connection [HikariProxyConnection@1154774545 wrapping com.mysql.cj.jdbc.ConnectionImpl@4664e639] for JDBC transaction
Switching JDBC Connection [HikariProxyConnection@1154774545 wrapping com.mysql.cj.jdbc.ConnectionImpl@4664e639] to manual commit

...
Transaction synchronization suspending SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@571ff6bc]
Acquired Connection [HikariProxyConnection@356317124 wrapping com.mysql.cj.jdbc.ConnectionImpl@1e0e3cb5] for JDBC transaction
Switching JDBC Connection [HikariProxyConnection@356317124 wrapping com.mysql.cj.jdbc.ConnectionImpl@1e0e3cb5] to manual commit

从这个日志中Transaction synchronization suspending SqlSession可以看到,因为使用Spring事务的REQUIRES_NEW传播类型,导致一个请求会同时占用多个连接,没有释放。这样就可能导致获取连接的死锁

解决办法

  • 设置连接超时时间,当获取连接的时间超过阈值时,就会退出事务,释放事务占用的连接。这样就可以破坏死锁条件spring.datasource.hikari.connection-timeout: 3000

参考

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.07.17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题症状
  • 查看连接池情况
  • 查看请求日志
  • 解决办法
  • 参考
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档