我们有一个与DB2(LUW)数据库集成的spring应用程序。
在特定的流程中,我们有一个用@Transactional(timeout=60)
注释的方法>
在数据库负载沉重的情况下,我们观察到以上60秒的超时未能抛出准时例外。仅当数据库处理成功完成或完成时才执行此操作错误。
失败消息类似于以下消息:
2020-02-21 18:45:32,463错误...事务超时:截止日期为2020年2月21日星期五18:40:14 EET 2020
[注意,在数据库释放资源后引发了异常,在特定情况下具有锁定超时错误,由于配置的事务超时,我比预期延迟了约5分钟。
我试图通过手动导致数据库延迟来重现此行为。具体来说,我打电话我的应用程序中的sleep DB2过程的时间长于已配置的事务超时。我的测试结果相同,只有在睡眠操作成功结束后才引发异常。
我想用另一个数据库检查类似的情况,所以我创建了一个简单的Spring引导项目,它具有2个不同的概要文件,一个概要文件用于DB2,一个概要文件用于Postgres。在运行此示例时,我观察到了DB2的类似行为,即事务超时不会导致任何错误,或者仅在为DB2配置的睡眠时间(30秒)(比配置的事务超时(10秒)长)结束后才发生错误。
相反,Postgres的行为或多或少是我所期望的。与DB的连接会在事务超时时间过去的确切时间(10s)上结束,而不会等待睡眠操作完成(30s)。
示例项目为here。此处描述的示例如下:
package com.example.demo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service public class DemoService { @Autowired private DemoRepository repository; @Transactional(timeout = 10) public void sleep() { repository.sleep(); } }
package com.example.demo; public interface DemoRepository { void sleep(); }
package com.example.demo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; @Repository @Profile("db2") public class Db2DemoRepository implements DemoRepository { @Autowired private JdbcTemplate template; @Override public void sleep() { template.execute("call SYSIBMADM.DBMS_ALERT.SLEEP(30)"); } }
package com.example.demo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; @Repository @Profile("postgres") public class PostgresDemoRepository implements DemoRepository { @Autowired private JdbcTemplate template; @Override public void sleep() { template.execute("select pg_sleep(30);"); } }
我想事务超时会在Postgres中设置查询超时,而在DB2中不会这样做。我还尝试了以下DB2配置属性的多个值,但没有任何运气:
timerLevelForQueryTimeOut, interruptProcessingMode, queryTimeout
。对我的问题:
我们有一个Spring应用程序,它与DB2(LUW)数据库集成在一起。在特定的流程中,我们有一个用@Transactional(timeout = 60)注释的方法。在数据库负载很重的情况下,我们发现...
自从我发布问题以来已经有一段时间了,没有人发布答案,我将从问题的编辑部分中移出我的发现,这里:
解决方案似乎正在设置DB2的配置属性queryTimeoutInterruptProcessingMode=2
(而不是我最初认为的interruptProcessingMode)