春季交易管理问题?

时间:2012-08-14 11:00:41

标签: java spring hibernate

我正在使用spring和hibernate。我使用spring进行事务管理。我在课堂下面。

@Service
@Transactional(readOnly = true)
public class Sample implements SampleInterface{

@Override
public List<Some> getData(){

//gets data after that it updates something

setStatus(someId);

}

@Override
@Transactional
public void setStatus(Long someId){

//sets status

}

}

如果我不为getData()保留@Transactional,那么我会得到以下异常。

Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode

如果我为getData()保留@Transactional,那么它将正确保存。这是一个什么问题?我怎么用setStatus()的@Transactional。我还需要为getData()保留@Transactional,因为它调用了一个公共方法来设置状态吗?

谢谢!

2 个答案:

答案 0 :(得分:5)

问题有点复杂,是由于调用 setStatus()内的getData() 引起的。当您从外部调用getData()时,实际上是在调用Spring框架为您创建的Java代理。此代理应用事务行为(启动只读事务)并委托给您的实际服务类。这很好。

但是,当您致电setStatus()时,您绕过交易代理并直接致电您的服务。换句话说,setStatus()的请求未被拦截,@Transactional 被忽略

没有简单的方法可以解决这个问题,也有同样的问题。在同一个类中调用公共方法时,您必须格外小心。

另见

答案 1 :(得分:1)

当你调用getData(在方法上没有@Transactional)时,Spring将启动一个只读事务,因为这是你的类的默认值,当getData调用setStatus时,Spring将使用现有的rad only事务而不是创建一个新事务。这就是你获得例外的原因。

默认事务传播是PROPAGATION REQUIRED。在http://static.springsource.org/spring/docs/3.0.x/reference/transaction.html#tx-propagation

了解有关该主题的更多信息