2010-09-06 40 views
0

我有两个java应用程序:其中一个插入记录到表1。 第二个应用程序先读取N个项目并将其删除。 当第一个应用程序插入数据密集型时,第二个失败,当我尝试删除任何CannotSerializeTransactionException行时。我没有看到任何问题:只有在插入事务完成时,插入的项目才会在选择/删除中可见。我该如何解决它?谢谢。插入期间数据库删除失败

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() - 睡眠

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

您可能需要显示您正在使用哪些代码来帮助人们 – 2010-09-06 14:32:05

+0

您如何控制交易?你的两个应用程序在同一个容器中运行吗? – rsilva4 2010-09-06 14:36:30

+0

不,应用程序是分开的:第一个是基于tomcat的webservice,第二个是在另一个服务器上运行的java standalone – alex543 2010-09-06 14:38:48

回答

1

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

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

0

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

在我看来,你混合了来自两个不同类别的常量:你不应该通过TransactionDefinition.ISOLATION_SERIALIZABLE而不是Connection.TRANSACTION_SERIALIZABLEsetIsolationLevel方法吗?

为什么你要设置隔离级别呢? Oracle的默认隔离级别(读取已提交)通常是一致性和速度之间的最佳折衷方案,应该很好地适用于您的情况。

+1

在Oracle中,会话永远不会读取其他会话的未提交数据。 – 2010-09-06 23:10:03