【问题标题】:Connection dies after exception from mysqlmysql异常后连接终止
【发布时间】:2020-08-30 05:07:17
【问题描述】:

当我从 mysql 得到一个异常时,如下异常

19:36:35,712 WARN  [org.hibernate.engine.jdbc.spi.SqlExceptionHelper]  - SQL Error: 1205, SQLState: 40001
19:36:35,713 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper]  - Lock wait timeout exceeded; try restarting transaction
org.springframework.dao.PessimisticLockingFailureException: could not execute statement; SQL [n/a]; nested exception is org.hibernate.PessimisticLockException: could not execute statement

该特定连接处于错误状态,然后 10 分钟后我收到以下错误

19:48:41,859 WARN  [com.mchange.v2.c3p0.impl.NewPooledConnection]  - [c3p0] A PooledConnection that has already signalled a Connection error is still in use!
19:48:41,859 WARN  [com.mchange.v2.c3p0.impl.NewPooledConnection]  - [c3p0] Another error has occurred [ java.sql.SQLNonTransientConnectionException: No operations allowed after connection closed. ] which will not be reported to listeners!

Caused by: com.mysql.cj.exceptions.CJCommunicationsException: The last packet successfully received from the server was 716,308 milliseconds ago. The last packet sent successfully to the server was 716,308 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem

通常当发生应用程序级异常时,事务回滚并且连接可用于将来的请求。

Mysql 的例外情况如何实现?

我使用 java spring hibernate mysql 和 c3p0

这是配置

hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
hibernate.hbm2ddl.delimiter=;
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=250
hibernate.c3p0.checkout_timeout=120000
hibernate.c3p0.test_connection_on_checkin=true
hibernate.c3p0.idle_connection_test_period=300
hibernate.archive.autodetection=class
hibernate.hbm2ddl.auto=validate

代码位于@Transactional 函数中

    @Override
    @Transactional(
            rollbackFor = Exception.class)
    public Long create() {
       //Hibernate and queryDsl code
    }

或者有时我必须像这样手动管理事务,因为如果最后一个函数失败,我不想回滚。我相信这是导致问题的功能。

public void function(){
try {
    final TransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
    final TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionDefinition);
    try {
        //Hibernate and QueryDsl code

        entityManager.flush();
        platformTransactionManager.commit(transactionStatus);
    } catch(Throwable t) {
        LOG.error(t);
        platformTransactionManager.rollback(transactionStatus);
        entityManager.clear();
        throw t;
    }
    // Call a transactional function
    transactionFunction();
}  

}

编辑

删除了关于重复键错误的部分,因为我现在可以确认它与问题无关。

【问题讨论】:

  • Spring 从 c3p0 迁移到 HikariCp,可以考虑更换连接池吗?
  • 尝试清除脚本中的会话。
  • @PeterDarmis 我确实调用了 entitymanager.clear() 但在等待超时异常后连接仍处于不良状态

标签: mysql spring hibernate c3p0


【解决方案1】:

这是因为管理不善的实时会话或做所有事情的选项,甚至查询,或者因为选择不当的事务隔离级别

【讨论】:

  • 我认为你应该删除配置文件中除方言之外的每一行并运行
【解决方案2】:

尝试更改此设置: - wait_timeout 默认值为 28.800 秒。 - interactive_timeout 默认值为 28.800 秒。 - innodb_lock_wait_timeout 默认值 50 秒。 (如果你使用的是 INNODB)

p.s:第二个错误是关于您的数据中的重复条目,在您用作主键的字段中,也许您需要检查发送到 mysql 的重复数据

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-05
    • 1970-01-01
    • 2019-01-21
    • 1970-01-01
    • 1970-01-01
    • 2011-05-16
    相关资源
    最近更新 更多