简体   繁体   English

春季交易管理问题?

[英]issue with spring transaction management?

I am using spring and hibernate. 我正在使用Spring和Hibernate。 i am using spring for transaction management. 我正在使用Spring进行事务管理。 i have below class. 我有下课。

@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

}

}

If i dont keep @Transactional for getData() then i get below exception. 如果我不为getData()保留@Transactional,那么我将获得以下异常。

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

if i keep @Transactional for getData() then it will save properly. 如果我为getData()保留@Transactional,则它将正确保存。 what is an issue here? 这里有什么问题? any how i have @Transactional for setStatus(). 任何我有@Transactional为setStatus()。 Still do i need to keep @Transactional for getData() as it is calling a public method which will set the status? 我仍然需要为getData()保留@Transactional,因为它正在调用将设置状态的公共方法?

Thanks! 谢谢!

The problem is a bit complex and is caused by calling setStatus() inside getData() . 这个问题有点复杂,是由于 getData() 内部调用setStatus()引起的。 When you are calling getData() from outside, you are actually calling a Java proxy created for you by Spring framework. 从外部调用getData()时,实际上是在调用Spring框架为您创建的Java代理。 This proxy applies transaction behaviour (starts read-only transaction) and delegates to your actual service class. 该代理应用事务行为(启动只读事务)并委托给您的实际服务类。 This works fine. 这很好。

However, when you call setStatus() , you are bypassing the transactional proxy and calling your service directly. 但是,当您调用setStatus() ,您将绕过事务代理并直接调用服务。 In other words the request to setStatus() is not intercepted, and @Transactional is ignored . 换句话说于该请求setStatus()不拦截, @Transactional 被忽略

There is no easy way to deal with this problem and has the same issue. 没有简单的方法可以解决此问题,而也存在相同的问题。 You just have to be extra careful when calling public methods inside the same class. 在同一类中调用公共方法时,您只需要格外小心。

See also 也可以看看

When you call getData (without @Transactional on the method) Spring will start a read only transaction as that is the default for your class and when getData calls setStatus Spring will use the existing rad only transaction instead of creating a new one. 当您调用getData(方法上没有@Transactional)时,Spring将启动一个只读事务,因为这是您的类的默认设置,当getData调用setStatus时,Spring将使用现有的仅rad事务,而不是创建一个新的事务。 That's the reason you are getting the exception. 这就是您得到例外的原因。

The default transaction propagation is PROPAGATION REQUIRED. 默认事务传播为“需要传播”。 Read more on the topic at http://static.springsource.org/spring/docs/3.0.x/reference/transaction.html#tx-propagation http://static.springsource.org/spring/docs/3.0.x/reference/transaction.html#tx-propagation上阅读有关该主题的更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM