2014-12-02 313 views
1

示例代码:Spring只有只读的PROPAGATION_SUPPORTS事务,你需要提交吗?

protected Session session() { 
     return (Session) getEntityManager().getDelegate(); 
} 

session().createCriteria(entityClass) 

会话()个createCriteria第一次调用()抱怨说,如果没有可用的事务会话被关闭。

所以我创建使用只读事务:

TransactionTemplate template = new TransactionTemplate(getTransactionManager()) 
template.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); 
template.setReadOnly(true); 

TransactionStatus status = getTransactionManager().getTransaction(template); 

我需要提交该事务。 的getTransactionManager()提交(状态);

的问题是,如果这个承诺,我会需要另一个事务稍后为:

criteria.list(); 

,并与该问题是第二次,这是一个不同的事务从一个用于获取会话,并导致错误。它会抱怨它已经关闭。

session()。createCriteria和criteria.list必须在看起来相同的事务中使用。但是我的代码在方法中有这些,因此除非session.createCriteria事务保持未提交状态,否则没有很好的方法来确保这些方法单独工作。

我可以安全地离开TransactionDefinition.PROPAGATION_SUPPORTS事务未提交吗?我可以创建多少次这样的交易?

回答

3

不,你不能把它当作未经整理。只读对于底层事务管理器来说更多的是暗示当前事务上下文中不允许突变。如果您稍后需要访问同一个事务,也许您需要稍微改变一下设计。为什么不在你方法的调用者中打开事务并在那里处理呢?或者尝试使用基于声明或注解的方法?

+0

是的,一个选项是打开它被调用的地方,这是我会选择的方式。我不喜欢基于注解的方法。基于声明的方法是什么意思? – momomo 2014-12-02 15:01:00

+0

声明性意味着使用XML的AOP。 – Nazgul 2014-12-02 15:01:51

+0

哦,哦。不,我喜欢我的方式。实际上,我将lambda传递给一个supportsTransaction方法,所以它比@Transactional方法好得多,如果你问我的话,这个方法就是一团糟,当一个新的愚蠢的开发人员接手。这几乎就像重新学习Javascript和HTML的所有怪癖。我试图连接AspectJ一次,但当时没有工作。我终于破解了基于lambda方法的交易! – momomo 2014-12-02 15:05:26