问题
This is my Repository layer:
class RepositoryImpl implements Repository{
@Override
public Serializable saveOrUpdate(Object obj) {
return getSession().save(obj);
}
@Override
public Object get(Class refClass, Serializable key)
{
return getSession().get(refClass, key);
}
}
This is my Service layer:
class ServiceImpl implements Service{
@Autowired
Repository repository;
@Override
@Transactional
public Object findUserById(Serializable key) {
// TODO Auto-generated method stub
return repository.get(User.class,key);
}
@Override
@Transactional
public Serializable saveUser(Object o) {
// TODO Auto-generated method stub
return repository.saveOrUpdate(o);
}
}
Here I am accessing and updating objects asynchronously:
class SomeClass{
@Autowired
Service service;
public void asynchronousSaveOrUpdate(){
User u = service.findUserbyId(1);
service.saveUser(1);
}
public void asynchronousfindUsersById(){
service.findUserbyId(1);
}
}
I got this exception:
[1236]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.deadline.core.model.User#1236]
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:672)
at org.springframework.orm.hibernate3.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:793)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:664)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
Note: I don't want Transactional
for ServiceImpl.findUserById() method.
Doing @Transactional(readOnly =true)
or @Transactional(propagation =Propagation.REQUIRES_NEW)
will solve this problem?
By calling session.merge()
this issue will be solved, however I cannot use it.
回答1:
You'll have to provide a little more information about what is going on. Is this error occurring every time you save a user, or only when you call saveUser(user)
at the same time from multiple threads? Or is it happening anytime you call findUserById()
or saveUser()
?
You might want to look into the Isolation parameter for the @Transactional
annotation. The default is Isolation.DEFAULT
(which is the "...default isolation level of the underlying datastore").
The way you are using this function should determine what value you want to supply for this argument. Will your saveUser(user)
function almost always conflict with with another call to that function? Then you might want to use:
@Transactional(isolation = Isolation.READ_COMMITTED)
Edit: I will say it does sound like this is functioning properly, though. It makes sense that if your object is modified in another thread, and then you try to commit that same object from another thread at the same time, you'd get StaleObjectStateException
来源:https://stackoverflow.com/questions/20324691/spring-hibernate-optimistic-locking-issue