Spring 4.1升级导致事务传播问题

时间:2015-03-11 05:06:22

标签: spring transactions spring-transactions

我正在尝试将我的应用程序从spring 3.3.x升级到Spring 4.1。大多数升级都进展顺利,但我们发现有关交易传播的一些奇怪问题。我们有一个使用@Transactional(read-only = true)注释的服务层类方法,调用另一个用@Transactional注释的低层类方法(只读= false)。它们中的任何一个通过接口代理,日志显示TransactionInterceptor是调用。但是当我们在数据库上调用save时。

“连接是只读的。不允许导致数据修改的查询;”

弹簧的早期版本与弹簧4.0.9一样完美。但是一旦我切换到4.1,就会抛出这个错误。有任何想法吗 ?我的印象是,如果当前事务以只读方式启动并且我已经使用了一段时间,那么在调用期间任何时候都会将事务修改为读写。下面是我们正在做的事情的代码。我们使用Hibernate 4.1和JpaTransactionManager作为我们的事务管理器。

public class Service1Impl implements Service1{

public Service2 service2;
@Transactional(read-only=true)
public Job processJob( Data data){
   .....
    service2.saveJob(data);
 }
}


public class Service2Impl implements Service2{

@Transactional(read-only=false)
public Job saveJob( Data data){
   .....

 }
}

非常感谢任何帮助或建议

由于

2 个答案:

答案 0 :(得分:1)

属性read-only不存在。它是readOnly

当事务管理器找到Transactional注释时,所有代码都在一个全局事务中执行。由于您在Service1中启动了只读事务,Transactional注释将被Service2忽略,并且不会提交任何更改。只有在您确定下划线交易中需要进行任何更改时,才使用readonly标志。如果您知道,注释方法将进行一些更改,或者如果它调用另一个正在修改数据的服务/方法,则永远不要使用readOnly=true

如果您想在readOnly=false中使用Service2新的transacton,可以使用此功能:

@Transactional(propagation=Propagation.REQUIRES_NEW)
public Job saveJob( Data data){...}

这将导致当您输入此方法时,事务管理器将始终启动新事务。但是这也可能会导致一些问题,因为如果在此方法中发生某些异常,则不会在启动此方法的事务中执行回滚(在这种情况下,事务在Service1中启动)。

答案 1 :(得分:0)

发现这在4.1的春天得到了改善和解决。我在春季jira发布了这个问题,得到了回应

https://jira.spring.io/browse/SPR-12807

显然这是在春季3.x中打开的错误,但在4.1版本中解决了。最初的错误就在这里 https://jira.spring.io/browse/SPR-8959

所以它现在按照需要工作但是可以提供自定义的HibernateJpaDialect并将prepareConnection设置为false以默认为旧行为。

由于