jta - Atomikos 事务超时和春季重试
问题描述
我们正在使用 atomikos 进行分布式事务管理。对于非常大的文件处理,我可以在进程开始后 300 秒在日志中看到以下条目。
"message" : "Transaction xxxxxxxx.tm123 has timed out and will rollback.",
"logger_name" : "com.atomikos.icatch.imp.ActiveStateHandler",
"thread_name" : "Atomikos:1234",
我们已将超时设置为 300 秒。com.atomikos.icatch.default_jta_timeout=300000
但是对于需要将每一行保存到数据库的非常大的文件(一年一次),即使在 300 秒后它也会继续保存到表中。进程结束大约 30 分钟后,我们可以在几毫秒内看到数千次日志文件中的以下警告。
"message" : "Forcing close of pending statement: oracle.jdbc.driver.OraclePreparedStatementWrapper",
"logger_name" : "com.atomikos.jdbc.AbstractConnectionProxy",
使用重试机制的 Rest 服务org.springframework.retry.annotation.Retryable
再次运行,但这次由于 Hibernate 缓存而运行得更快。但是重试有副作用,比如部分过程会像发送文件一样运行两次,从而导致一些问题。我已经实现了一个基本的解决方案,比如维护标志是否正在发送文件,或者在事务管理级别寻找更好的解决方案。
有没有人遇到过与atomikos类似的问题?你是怎么处理的呢
下面是休息服务代码。我们没有看到它进入异常块,因为在日志中没有看到错误。尚未尝试将 @Transactional 移动到 mainProcess() 方法。
@RequestMapping("someProcess/")
@Transactional
@Retryable(
include = {Exception.class, JpaSystemException.class, IOException.class},
maxAttemptsExpression = "#{${retry.maxAttempts}}",
backoff = @Backoff(
delayExpression = "#{${retry.retryDelay}}",
maxDelayExpression = "#{${retry.maxDelay}}",
multiplierExpression = "#{${retry.multiplier}}"
)
)
public void someProcess() throws Exception {
try {
mainProcess();
} catch (Exception e) {
logError(e);
throw e;
}
我们正在使用 atomikos 4.0.6 和 spring boot 2.1.4。
解决方案
推荐阅读
- reactjs - 如何在本机反应中在顶部标签栏周围留出空间?
- c - 使用 peprocessor 宏生成函数调用
- angular - 服务器渲染部分 DOM 并将其注入 Angular 应用程序
- aws-php-sdk - 如何在 PHP 中从 aws-marketplace 调用 ResolveCustomer 和 GetEntitlements?
- go - 如何加密字符串或 JSON
- android - 房间 - 按存储在字符串中的日期排序
- python - 如何捕获函数的输出并使用生成器实时重定向它?
- postman - 如何在邮递员测试中验证数组响应值?
- php - 安装 mysqli 扩展后的 Docker php:php7.4-apache boot-loop
- python - iOS camera output rotated 90 degrees left