1

我正在实现同时写入数据库和 Oracle Coherence 3.7.1 并希望使整个操作具有事务性。

我想对我的方法进行批评。

目前,我已经创建了这样的外观类:

public class Facade {
   @EJB
   private JdbcDao jdbcDao;
   @EJB
   private CoherenceDao coherenceDao;

   @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
   private void updateMethod(List<DomainObject> list) {
      jdbcDao.update(list);
      coherenceDao.update(list);
   }
}

我想 JDBC DAO 不需要对事务做任何特定的事情,如果发生某些事情,Hibernate 会抛出某种 RuntimeException。

public class JdbcDao {
   private void update(List<DomainObject> list) {
       // I presume there is nothing specific I have to do about transactions.
       // if I don't catch any exceptions it would work just fine
   }
}

这是有趣的部分。如何使 Coherence 支持事务?我想我应该在 update() 方法中打开一致性事务,并且对于其中的任何异常,我应该自己抛出 RuntimeException 吗?

我目前正在考虑这样的事情:

public class CoherenceDao {
   private void update(List<DomainObject> list) {
      // how should I make it transactional?
      // I guess it should somehow throw RuntimeException?

      TransactionMap mapTx = CacheFactory.getLocalTransaction(cache);
      mapTx.setTransactionIsolation(TransactionMap.TRANSACTION_REPEATABLE_GET);
      mapTx.setConcurrency(TransactionMap.CONCUR_PESSIMISTIC);

      // gather the cache(s) into a Collection
      Collection txnCollection = Collections.singleton(mapTx);

      try {
         mapTx.begin();

         // put into mapTx here

         CacheFactory.commitTransactionCollection(txnCollection, 1);
      } catch (Throwable t) {
         CacheFactory.rollbackTransactionCollection(txnCollection);
         throw new RuntimeException();
      }

   }
}

这种方法会按预期工作吗?

4

1 回答 1

0

我知道你在一年前问过这个问题,而我现在的回答可能在一年后对你来说没有价值,但我仍然试一试。

只要在您的方法调用之后没有 RuneTimeException ,您尝试执行的操作 coherenceDao.update(list);可能会假设您在该行之后没有任何代码行,但这还不是全部。

例如:您的数据库中可能有一些可延迟的约束。updateMethod(List<DomainObject> list)当容器尝试提交在方法退出时和方法调用之后的事务时,将应用这些约束coherenceDao.update(list)。另一种情况是在coherenceDao.update(list)执行之后但仍在事务提交之前与数据库的连接超时。在这两种情况下,您的 CoherenceDAO 类的更新方法都安全可靠地执行,并且您的一致性事务不再回滚,这将使您的缓存处于不一致的状态,因为您将因为这些 DB 或 Hibernate 异常而获得 RuneTimeException,这将导致您的容器要回滚的托管事务!

于 2014-11-11T20:13:04.770 回答