好的人。我已经阅读了很多文档。而我不知为何会发生这种情况。
与其他许多人一样,我们有一个与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
时没有考虑它答案 0 :(得分:1)
根据this answer,Spring仅为您提供事务管理器的界面,实现可能有所不同。但是,大多数事务管理器实现都会在@Transactional调用期间关闭自动提交,然后在提交后将其返回到之前的状态。
也就是说,在某些数据库上,有一些方法可以在外部事务内部执行自主事务,这些事务对于您的应用程序或Spring可能不可见。我知道Oracle允许这样做。您是否检查了桌上的所有触发器?我在一个具有审计触发器的应用程序上工作,该触发器会在这种情况下将孤立数据强制进入某些表。您能告诉我们您正在使用哪个数据库吗?
答案 1 :(得分:1)
来自Database JDBC Developer's Guide:
如果禁用了自动提交模式,并且您在没有显式提交或回滚上一次更改的情况下关闭了连接,则将运行隐式COMMIT操作。
也许您正在遇到这种情况。
答案 2 :(得分:0)
尝试:
@Transactional(propagation = Propagation.REQUIRES_NEW)
希望它能工作