我正在开发一个 Spring Boot 应用程序,我有一个调用外部 API 并写入数据库的方法。这是结构:
method() {
call external API
save to DB
call another external API
save to DB
}
我尝试将
@Transactional
注释放在方法签名上,但我意识到它效率低下。所以我找到了另一种方法:使用 TransactionTemplate
对象以编程方式将数据库写入封装在事务中。
无论该方法发生什么错误,我都需要取消写入数据库。因此,如果对外部 API 的第二次调用失败,我必须回滚到第一次写入。就像第二次写入数据库失败一样,我必须取消第一次写入。我该怎么办?基本上我需要通过更有效的实现来获得使用
@Transactional
注释的效果。
现在我正在尝试这样的方式:
method() {
call external API
transactionTemplate.execute(status -> save to DB);
call another external API
transactionTemplate.executeWithoutResult(status -> save to DB);
}
但我注意到这两笔交易并没有“关联”:
method() {
call external API
transactionTemplate.execute(status -> save to DB);
call another external API
if(true) throw new RuntimeException(); // first write not rolled back
transactionTemplate.executeWithoutResult(status -> save to DB);
}
那是因为您正在打开两个交易,而不是在同一个交易中进行操作
method() {
call external API
transactionTemplate.execute(
status -> save to DB
call another external API
status -> save to DB
);
}
即使理想情况下,第二次 API 调用也应该在打开交易之前完成
method() {
call external API
prepare mock entity
call another external API
transactionTemplate.execute(
status -> save to DB
status -> save to DB
);
}