java - Spring @Transactional 在异常时始终如一地回滚事务
问题描述
好吧,伙计们。我已经阅读了很多文档。我不知道为什么会这样。
像许多其他人一样,我们有一个与 Oracle 数据库接口的服务。这是一个非常标准的设置
@Service
public class DaoService {
private JdbcTemplate jdbcTemplate;
private SimpleJdbcInsert insertA;
private SimpleJdbcInsert insertB;
private SimpleJdbcInsert insertC;
@Autowired
public Dao(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
// Assume all Inserts are initialized
}
@Transactional(rollbackFor = Exception.class)
public void insertStuff(Stuff stuff) {
insertA.execute(stuff.A);
// Suppose a connection failed here
insertB.executeBatch(stuff.B);
insertC.executeBatch(stuff.C);
}
现在这就是我们的问题。对于 99% 的回滚,它们是正常的。
当连接因未知原因而关闭时,就会出现问题。异常消息是
TransactionSystemException: Could not roll back JDBC transaction;
nested exception is java.sql.SQLException: "The connection is closed"
看,它试图按预期回滚。但问题是在 DB 中的 stuffA 会在 stuffB 中徘徊,而 stuffC 不会。这种情况只发生在 1% 的时间里。(又名,有时尽管回滚失败,但数据库中不会有任何“东西”。
我理解错了吗?我认为spring只在成功交易结束时提交?尽管在@Transactional 中进行,任何人都知道如何停止这些部分提交?
ps 值多少钱。自动提交默认为开启。但是我读到当某事是@Transactional 时没有考虑到它
解决方案
根据这个答案,Spring 只为您提供事务管理器的接口,实现可能会有所不同。但是,大多数事务管理器实现将在 @Transactional 调用期间关闭自动提交,然后在提交后将其返回到先前的状态。
话虽如此,在某些数据库上,有一些方法可以在您的应用程序或 Spring 可能看不到的外部事务中执行自治事务。我知道甲骨文允许这样做。您是否检查了表上的所有触发器?我开发了一个应用程序,它有一个审计触发器,在这种情况下会强制将孤立数据放入某些表中。您能告诉我们您使用的是哪个数据库吗?