mysql异常后连接终止

Posted

技术标签:

【中文标题】mysql异常后连接终止【英文标题】:Connection dies after exception from mysql 【发布时间】: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() 但在等待超时异常后连接仍处于不良状态 【参考方案1】:

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

【讨论】:

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

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

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

【讨论】:

以上是关于mysql异常后连接终止的主要内容,如果未能解决你的问题,请参考以下文章

WinHttpException:与服务器的连接异常终止

终止空闲的mysql连接

centosc程序异常终止

在抛出 'std::length_error' 的实例后调用终止

ExecutorService 使用 invokeAll 和超时异常后可调用线程上的超时未终止

Java:抛出异常后如何终止执行后面的代码?