Unexpected exception on closing transaction.

0x00 BUG出现背景

事情是这样的,在我最近的一个任务墙网站上,实现了这么一个功能:任务墙有若干任务卡片,任务卡片 有一个属性是今日状态,标志今日是否已完成该任务的一个状态显示。在数据持久层以card表的一个todayStatus字段来记录着,很明显因为是需要每日定时去更新重置它,于是就在后端使用TimerTask类实现定时任务的功能,设置好每隔24小时执行一次,每日8点自更新今日状态字段的值。之前runing一直没有问题,但是最近不知什么原因,貌似不行了,中间我有动过数据库表设计,不知是不是哪一步影响到了?具体原因我也没查找,当我第一次发现时,是有一次我进行打卡的时候提醒今日已完成打卡,我当时懵了,经过查看发现没有重置,当时也没有太在意,重启了服务器,后来就正常了几天,结果问题不解决它永远是问题,今天一大早看到有朋友通过任务墙提醒我今天这么早就完成了??我赶去一看,又没有重置今日状态,算了,是问题总要解决的,开始吧!

0x01 BUG调试过程

首先我是在本地跑了一下,查看日志没有问题啊

然后又去数据库看了一眼,确定没出问题。。。

看来又是一个本地运行正常,换到生产环境就出的BUG。没办法先去搂一眼日志再说。

看样子确实出问题了.....

[WARN]  [Timer-0] o.a.i.e.BaseExecutor - Unexpected exception on closing transaction.  Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed. 
Exception in thread "Timer-0" org.apache.ibatis.exceptions.PersistenceException: 
### Error updating database.  Cause: org.apache.ibatis.transaction.TransactionException: Error configuring AutoCommit.  Your driver may not support getAutoCommit() or setAutoCommit(). Requested setting: false.  Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 31,859,823 milliseconds ago.  The last packet sent successfully to the server was 0 milliseconds ago.
### The error may exist in cn/imyjs/mapper/CardMapper.java (best guess)
### The error may involve cn.imyjs.mapper.CardMapper.updateAllTodayStatus
### The error occurred while executing an update
### Cause: org.apache.ibatis.transaction.TransactionException: Error configuring AutoCommit.  Your driver may not support getAutoCommit() or setAutoCommit(). Requested setting: false.  Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 31,859,823 milliseconds ago.  The last packet sent successfully to the server was 0 milliseconds ago.
	at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:199)
	at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:67)
    // .......

通过一番仔细研读可以发现是TransactionException也就是事务异常,关闭事务时出现意外异常。

Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.

原因:com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:连接关闭后不允许执行任何操作。

看来好像是连接关闭导致的异常??

紧接着给出了导致出现异常的线程Exception in thread "Timer-0" org.apache.ibatis.exceptions.

下面看具体的错误信息:

Error updating database. Cause: org.apache.ibatis.transaction.TransactionException: Error configuring AutoCommit. Your driver may not support getAutoCommit() or setAutoCommit(). Requested setting: false. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

更新数据库时出错。原因:org.apache.ibatis.transaction。TransactionException:配置自动提交时出错。您的驱动程序可能不支持getAutoCommit()或setAutoCommit()。请求的设置:false。原因:com.mysql.jdbc.exceptions.jdbc4。通信异常:通信链路故障

再往下走就是提示的可能出现BUG 的字节码文件的具体位置了

### The error may exist in cn/imyjs/mapper/CardMapper.java (best guess)
### The error may involve cn.imyjs.mapper.CardMapper.updateAllTodayStatus
### The error occurred while executing an update

 

果然还是出了问题。

通过调试日志不难发现是更新数据库时出错,再有就是貌似是事务连接关闭,导致的事务异常。

0x02 BUG解决方法

紧接着拿着问题去查询解决问题:说是mysql 有一个侦测的机制,8小时的连接没有动作,就会认为是死的,就会出现以上错误,所以要修改数据库配置,用的mybatis 有一个配置直接配上就行了。在jdbc 的url 中开启 autoReconnect=true

修改mybatis配置文件:

<environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!--数据库连接信息-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/db1?rewriteBatchedStatements=true&amp;characterEncoding=UTF-8&amp;useSSL=false&amp;autoReconnect=true"/>
                <property name="username" value="root"/>
                <property name="password" value="5555555"/>
                <property name="poolPingEnabled" value="true"/>
                <property name="poolPingQuery" value="select 1"/>
                <property name="poolPingConnectionsNotUsedFor" value="3600000"/>
            </dataSource>
        </environment>

 

配置连接池时,需要声明三个属性:

  1. poolPingEnabled - 默认值是false,当值为true的时候,将开启ping机制。
  2. poolPingQuery - 对数据库进行ping时所使用的sql。
  3. poolPingConnectionsNotUsedFor - 默认值是0,单位是毫秒。我们不能在每次使用连接池之前,都使用ping机制,这会使每一条sql的执行,都要额外执行一次ping语句。所以使用此属性来避免这种不合理做法。我们只针对闲置时间超过某个时间的连接,进行ping。本例中的值为1小时,当从连接池中拿出的连接闲置超过1小时,才会对它进行ping。

0x03 微信关注

WeChat

 

 

本站为非盈利性站点,所有资源、文章等仅供学习参考,并不贩卖软件且不存在任何商业目的及用途,如果您访问和下载某文件,表示您同意只将此文件用于参考、学习而非其他用途。
本站所发布的一切软件资源、文章内容、页面内容可能整理来自于互联网,在此郑重声明本站仅限用于学习和研究目的;并告知用户不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。
如果本站相关内容有侵犯到您的合法权益,请仔细阅读本站公布的投诉指引页相关内容联系我,依法依规进行处理!
作者:理想
链接:https://www.imyjs.cn/archives/568
THE END
二维码
Unexpected exception on closing transaction.
0x00 BUG出现背景 事情是这样的,在我最近的一个任……
<<上一篇
下一篇>>
文章目录
关闭
目 录