Spring @Transactional会一如既往地回滚事务

时间:2018-09-25 22:00:47

标签: java spring spring-data rollback transactional

好的人。我已经阅读了很多文档。而我不知为何会发生这种情况。

与其他许多人一样,我们有一个与oracle db接口的服务。这是一个非常标准的设置

@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"

看,它试图按预期方式回滚。但是问题是,在数据库中流连的stuffA不会填充stuffB,而stuffC不会。这种情况仅发生1%的时间。 (又名,有时即使回滚失败,数据库中也没有“东西”。

我理解错了吗?我认为spring仅在成功交易结束时提交?任何人都有一个想法,尽管在@Transactional中进行了操作,我如何才能停止这些部分提交?

p.s。物有所值。默认情况下,自动提交功能为开。但是我读到@Transactional

时没有考虑它

3 个答案:

答案 0 :(得分:1)

根据this answer,Spring仅为您提供事务管理器的界面,实现可能有所不同。但是,大多数事务管理器实现都会在@Transactional调用期间关闭自动提交,然后在提交后将其返回到之前的状态。

也就是说,在某些数据库上,有一些方法可以在外部事务内部执行自主事务,这些事务对于您的应用程序或Spring可能不可见。我知道Oracle允许这样做。您是否检查了桌上的所有触发器?我在一个具有审计触发器的应用程序上工作,该触发器会在这种情况下将孤立数据强制进入某些表。您能告诉我们您正在使用哪个数据库吗?

答案 1 :(得分:1)

来自Database JDBC Developer's Guide

  

如果禁用了自动提交模式,并且您在没有显式提交或回滚上一次更改的情况下关闭了连接,则将运行隐式COMMIT操作。

也许您正在遇到这种情况。

答案 2 :(得分:0)

尝试:

@Transactional(propagation = Propagation.REQUIRES_NEW)

希望它能工作