繁体   English   中英

Spring 3 DataSourceTransactionManager在与MySQL进行交易时偶尔会超时

[英]Spring 3 DataSourceTransactionManager sporadically timing out when getting transaction to MySQL

简而言之,当我在几分钟未使用事务后尝试建立连接时,第一次事务设置将失败。

当一切正常时,我的日志显示了一个简单事务的以下内容:

DEBUG: org.springframework.transaction.annotation.AnnotationTransactionAttributeSource - Adding transactional method 'getRecord' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,timeout_30; ''
DEBUG: org.springframework.jdbc.datasource.DataSourceTransactionManager - Creating new transaction with name [com.example.services.Service.getRecord]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,timeout_30; ''
DEBUG: org.springframework.jdbc.datasource.DataSourceTransactionManager - Acquired Connection [jdbc:mysql://dev-db.example.com:3306/example, UserName=foo@1.2.3.4, MySQL Connector Java] for JDBC transaction
DEBUG: org.springframework.jdbc.datasource.DataSourceTransactionManager - Switching JDBC Connection [jdbc:mysql://dev-db.example.com:3306/example, UserName=foo@1.2.3.4, MySQL Connector Java] to manual commit

但是,如果我有几分钟没有任何活动了,我将收到以下消息:

DEBUG: org.springframework.transaction.annotation.AnnotationTransactionAttributeSource - Adding transactional method 'getRecord' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,timeout_30; ''
DEBUG: org.springframework.jdbc.datasource.DataSourceTransactionManager - Creating new transaction with name [com.example.services.Service.getRecord]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,timeout_30; ''

到目前为止,我的观察:

  • 似乎是基于非活动状态,但是重新启动Tomcat后我立即看到了这种行为,尽管没有其他事件影响数据库,所以我认为它对网络元素(如MySQL服务器)处于非活动状态。
  • 当我的应用程序启动时,它会从数据库发出一些没有问题的非事务请求,因此它似乎与事务有关。
  • @Transactional表示法中的timeout元素在这种情况下无效。 它似乎最终会超时,但是需要15分钟(!)。
  • 当此事务请求正忙于超时时,我可以成功发出后续请求。
  • 似乎不是饥饿的本地连接池。 重新启动Tomcat之后,我已经看到了这一点。

当它最终超时时(我提到了15分钟!),我得到以下信息:

DEBUG: org.springframework.jdbc.datasource.DataSourceTransactionManager - Acquired Connection [org.apache.commons.dbcp.PoolableConnection@3269c671] for JDBC transaction
DEBUG: org.springframework.jdbc.datasource.DataSourceTransactionManager - Switching JDBC Connection [connection is closed] to manual commit
DEBUG: org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
DEBUG: org.springframework.jdbc.datasource.DataSourceUtils - Could not close JDBC Connection
ERROR: java.sql.SQLException: Already closed.
ERROR: org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 1,312,604 milliseconds ago.  The last packet sent successfully to the server was 924,748 milliseconds ago.
Caused by: java.net.SocketException: Connection timed out

运行Spring 3.1.1,mysql 5.1.32,commons-dbcp 1.4和commons-pool 1.5.4。

有人知道这是什么吗?

您的问题是MySQL服务器超时闲置的JDBC连接。 这与TransactionManager的设置无关。

看一下您的DataSource设置。 它应在连接检索上测试连接和/或验证池中的空闲连接。

在commons-dbcp中,您可以通过testOnBorrow和validationQuery属性设置对连接检索的测试。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM