我有两个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});}
答案 0 :(得分:1)
您是否也在第一次申请中使用Connection.TRANSACTION_SERIALIZABLE
?看起来像第一个应用程序锁表,所以第二个不能访问它(无法启动事务)。也许Connection.TRANSACTION_REPEATABLE_READ
就足够了?
可能你也可以配置第二个应用程序,当它无法访问资源时,不要抛出异常,而是等待它。
答案 1 :(得分:0)
这听起来好像是在阅读未提交的数据。你确定你正确设置了隔离级别吗?
在我看来,你正在混合来自两个不同类的常量:你不应该将TransactionDefinition.ISOLATION_SERIALIZABLE
而不是Connection.TRANSACTION_SERIALIZABLE
传递给setIsolationLevel
方法吗?
为什么要设置隔离级别? Oracle的默认隔离级别(读取已提交)通常是一致性和速度之间的最佳折衷,并且在您的情况下应该很好地工作。