插入期间数据库删除失败

时间:2010-09-06 14:28:48

标签: java oracle transactions

我有两个java应用程序:其中一个将记录插入Table1。 第二个应用程序读取前N个项目并将其删除。 当第一个应用程序插入数据密集型时,当我尝试使用CannotSerializeTransactionException删除任何行时,第二个应用程序失败。我没有看到任何问题:仅当插入事务完成时,插入的项目在select / delete中可见。我该如何解决?感谢。

 TransactionTemplate tt = new  TransactionTemplate(platformTransactionManager);  
    tt.setIsolationLevel(Connection.TRANSACTION_SERIALIZABLE);
    tt.execute(new TransactionCallbackWithoutResult() {                
    @Override
    protected void doInTransactionWithoutResult(TransactionStatus status) {
        List<Record> records = getRecords(); // jdbc select
        if (!records.isEmpty()) {
           try {
              processRecords(records); // no database
              removeRecords(records); // jdbc delete - exception here
           } catch (CannotSerializeTransactionException e) {
                 log.info("Transaction rollback");
            }
         } else {
           pauseProcessing();
             }
        }
   });

pauseProcessing() - sleep

public void removeRecords(int changeId) { String sql = "delete from RECORDS where ID <= ?";
        getJdbcTemplate().update(sql, new Object[]{changeId});}

2 个答案:

答案 0 :(得分:1)

您是否也在第一次申请中使用Connection.TRANSACTION_SERIALIZABLE?看起来像第一个应用程序锁表,所以第二个不能访问它(无法启动事务)。也许Connection.TRANSACTION_REPEATABLE_READ就足够了?

可能你也可以配置第二个应用程序,当它无法访问资源时,不要抛出异常,而是等待它。

答案 1 :(得分:0)

这听起来好像是在阅读未提交的数据。你确定你正确设置了隔离级别吗?

在我看来,你正在混合来自两个不同类的常量:你不应该将TransactionDefinition.ISOLATION_SERIALIZABLE而不是Connection.TRANSACTION_SERIALIZABLE传递给setIsolationLevel方法吗?

为什么要设置隔离级别? Oracle的默认隔离级别(读取已提交)通常是一致性和速度之间的最佳折衷,并且在您的情况下应该很好地工作。