1

我正在使用弹簧和休眠。我正在使用 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,因为它正在调用将设置状态的公共方法?

谢谢!

4

2 回答 2

5

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

但是,当您调用 时setStatus(),您将绕过事务代理并直接调用您的服务。换句话说,请求setStatus()不会被拦截,并且@Transactional 会被忽略

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

也可以看看

于 2012-08-14T11:09:32.657 回答
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阅读有关该主题的更多信息

于 2012-08-14T11:14:01.033 回答