spring hibernate optimistic locking issue

淺唱寂寞╮ 提交于 2021-01-28 06:14:55

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!