应用事务管理混乱导致的一个坑

栏目: Java · 发布时间: 7年前

内容简介:应用事务管理混乱导致的一个坑

Spring 的事务传播属性

org.springframework.transaction.annotation.Propagation 定义了 Spring 的事务传播属性:

  • REQUIRED: 支持当前事务,如果不存在则新建一个。

  • REQUIRES_NEW: 创建新的事务,如果当前存在一个则 suppend 当前的。

  • SUPPORTS: 支持当前事务,如果不存在则以非事务方式执行。

  • MANDATORY: 支持当前事务,如果不存在则抛出异常。

  • NOT_SUPPORTED: 以非事务方式执行,如果当前存在一个事务则 suppend 当前的。

  • NEVER: 以非事务方式执行,如果存在事务则抛出异常。

  • NESTED: 如果当前存在一个事务则以嵌套事务的方式执行。

一个生产问题

一开始是 DBA 反馈数据库出现两种现象:

  1. 出现一些操作做完但会话一直还在等待客户端的提交动作。
  2. 偶尔出现大量的行锁,导致 JVM 线程互相等待而假死。

有个获取流水号的方法 systemService.getSerialNo 的事务传播属性是 NOT_SUPPORTED 的,这个方法通过类似这样的 update t_serialno set serial_no = :newSerialNo where serial_key = :key and serial_no = :oldSerialNo SQL 语句进行更新,更新返回的受影响行数等于 1 认为新的流水号是不重复的,更新不成功则重试。

行锁就出现在这些流水号的更新上。

有些遗留代码需要直接使用数据库连接对象,包装成 ConnectionWrapper(Connection) 对象,这个 ConnectionWrapper 的构造函数把传入的 Connection 对象设置为非自动提交。

出问题的方法体大概如下:

public void submit() {
    Connection connection = sqlSessionTemplate.getConnection();
    ConnectionWrapper wrapper = new ConnectionWrapper(Connection);
    // ...
    String serialNo = systemService.getSerialNo(,,,);
}

sqlSessionTemplate.getConnection() 获得的连接默认是跟当前线程绑定的, systemService.getSerialNo 在没有事务的方法里,会重用当前线程的连接,然而此处这个连接没有启动提交事务的能力(如果 submit 方法上有声明事务,则会 suppend 当前事务,然后用一个新连接去完成非事务的操作)。该方法会多次获取流水号,在并发压力大时就会出现互相等待。

后续的代码并没有把 连接 设置回 自动提交,检查发现是采用的 DBCP 连接池在连接返回给池时会自动把连接设置为自动提交。

之前一直没想明白:事务管理都是由 Spring 管理的,为什么会出现事务做完了又不提交?就算有的采用了遗留代码导致没有手工提交事务,那么后续用到这个连接的其他请求的事务也不会提交,这应该很快就能发现才对呀,现实中好像没有出现。

行锁一直等待也是因为没有设置语句执行的超时时间(DBCP 1.4 好像没参数可设),在连接池获取连接上一直等待是因为没有设置获取连接的最大等待时间。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

C语言程序设计

C语言程序设计

K. N. King / 吕秀锋、黄倩 / 人民邮电出版社 / 2010-4 / 79.00元

时至今日, C语言仍然是计算机领域的通用语言之一,但今天的 C语言已经和最初的时候大不相同了。本书最主要的一个目的就是通过一种“现代方法”来介绍 C语言,书中强调标准 C,强调软件工程,不再强调“手工优化”。这一版中紧密结合了 C99标准,并与 C89标准进行对照,补充了 C99中的最新特性。本书分为 C语言的基础特性、 C语言的高级特性、 C语言标准库和参考资料 4个部分。每章末尾都有一个“问与......一起来看看 《C语言程序设计》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具