我正在实现对数据库和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()方法中打开coherence事务,并且在它内部有任何异常时,我应该自己抛出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();
}
}
}这种方法会像预期的那样工作吗?
发布于 2014-11-12 04:13:05
我知道你在一年前提出了这个问题,一年后我的回答对你来说可能不那么有价值,但我仍然会试一试。
只要在coherenceDao.update(list);的方法调用之后没有RuneTimeException,您可能会假设该行后面没有任何代码行,但这并不是全部。
举个例子:你的数据库中可能有一些可推迟的约束。这些约束将在容器尝试提交事务时应用,该事务位于updateMethod(List<DomainObject> list)的方法退出时,并且在您对coherenceDao.update(list)的方法调用之后。另一种情况类似于在coherenceDao.update(list)执行之后但在事务提交之前到数据库的连接超时。在这两种情况下,您的CoherenceDAO类的更新方法都被安全地执行,并且您的coherence事务不再回滚,这将使您的缓存处于不一致的状态,因为由于这些DB或Hibernate异常,您将获得一个RuneTimeException,这将导致您的容器管理的事务被回滚!
https://stackoverflow.com/questions/20091417
复制相似问题