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

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

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

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陷阱与缺陷

凯尼格 / 高巍 / 人民邮电出版社 / 2008-2-1 / 30.00元

作者以自己1985年在Bell实验室时发表的一篇论文为基础,结合自己的工作经验扩展成为这本对C程序员具有珍贵价值的经典著作。写作本书的出发点不是要批判C语言,而是要帮助C程序员绕过编程过程中的陷阱和障碍。.. 全书分为8章,分别从词法分析、语法语义、连接、库函数、预处理器、可移植性缺陷等几个方面分析了C编程中可能遇到的问题。最后,作者用一章的篇幅给出了若干具有实用价值的建议。.. 本书......一起来看看 《C陷阱与缺陷》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码