我正在使用 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,因为它正在调用将设置状态的公共(public)方法吗?
谢谢!
最佳答案
问题有点复杂,是调用setStatus()
里面 getData()
引起的。当您从外部调用 getData()
时,您实际上是在调用 Spring 框架为您创建的 Java 代理。此代理应用事务行为(启动只读事务)并委托(delegate)给您的实际服务类。这很好用。
但是,当您调用 setStatus()
时,您将绕过事务代理并直接调用您的服务。换句话说,对 setStatus()
的请求不会被拦截,并且 @Transactional
会被忽略。
没有简单的方法来处理这个问题并且ejb有同样的问题。在同一个类中调用公共(public)方法时,您必须格外小心。
另见
- > 8.6.1 Understanding AOP proxies - 官方文档
- > Spring pitfalls: proxying - 我的博客
关于java - Spring 事务管理的问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11950895/