【发布时间】:2020-06-26 20:49:43
【问题描述】:
我们有一个与 DB2 (LUW) 数据库集成的 spring 应用程序。
在一个特定的流程中,我们有一个用@Transactional(timeout=60)注释的方法
在数据库重负载时,我们观察到上述 60 秒的超时未能引发 准时例外。它仅在数据库处理成功完成或 有错误。
失败的消息如下所示:
2020-02-21 18:45:32,463 错误 ... 交易超时:截止日期为 2020 年 2 月 21 日星期五 18:40:14 EET 2020
请注意,在数据库释放资源后抛出异常,在特定情况下出现锁定超时错误,由于配置的事务超时,比我预期的晚了大约 5 分钟。
我试图通过手动导致数据库延迟来重现此行为。具体来说,我打电话给 我的应用程序中的睡眠 DB2 过程,时间长于配置的事务超时。我的测试结果是一样的,只有在sleep操作成功结束后才抛出异常。
我想用另一个数据库检查类似的场景,所以我创建了一个简单的 Spring boot 项目,其中包含 2 个不同的配置文件,一个用于 DB2,一个用于 Postgres。 运行这个示例,我观察到 DB2 的类似行为,即事务超时不会导致任何错误,或者它仅在为 DB2 配置的休眠时间(30 秒)(大于配置的事务超时(10 秒))结束后才会发生。
相反,Postgres 的行为或多或少是我所期望的。与数据库的连接在事务超时时间过去(10 秒)的确切时刻以异常结束,而无需等待睡眠操作完成(30 秒)。
示例项目是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。
所以我的问题:
- 我尝试重现问题并测试多个 DB 的方式是否有意义,还是我遗漏了什么?
- 这更重要,:有没有办法让 DB2 连接在事务超时达到其限制的确切时刻失败?
【问题讨论】:
-
您的 Db2 jdbc 驱动程序版本和类型是什么?从 ibm.com/support/pages/db2-jdbc-driver-versions-and-downloads 获取最新信息 在寻求 Db2 方面的帮助时,请始终指定您的 Db2 服务器平台(z/os、i 系列 os/400 或 linux/unix/windows)。
-
@mao 你说得对,我错过了这个。它是 DB2 LUW,驱动程序是
com.ibm.db2.jcc:db2jcc4:4.26.14,我相信它是最新的。你认为事务超时应该像我期望的那样工作吗? -
我不知道 Spring 在幕后做了什么,但如果普通 jdbc 的行为不像文档所述的那样,那么我会向 IBM 开一张票。不过,这些文档通常没有什么帮助。
标签: spring db2 spring-transactions db2-luw