Java spring hibernate 乐观锁问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20324691/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 01:05:17  来源:igfitidea点击:

spring hibernate optimistic locking issue

javaspringhibernatetransactionsspring-transactions

提问by Prabhakaran Ramaswamy

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 Transactionalfor ServiceImpl.findUserById() method.

注意:我不想要TransactionalServiceImpl.findUserById() 方法。

Doing @Transactional(readOnly =true)or @Transactional(propagation =Propagation.REQUIRES_NEW)will solve this problem?

@Transactional(readOnly =true)@Transactional(propagation =Propagation.REQUIRES_NEW)将解决这个问题?

By calling session.merge()this issue will be solved, however I cannot use it.

通过调用session.merge()此问题将得到解决,但是我无法使用它。

采纳答案by Paul Gray

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()?

您必须提供更多有关正在发生的事情的信息。每次保存用户时都会发生此错误,还是仅在saveUser(user)从多个线程同时调用时发生?抑或是随时发生的事情你打电话findUserById()还是saveUser()

You might want to look into the Isolationparameter for the @Transactionalannotation. The default is Isolation.DEFAULT(which is the "...default isolation level of the underlying datastore").

您可能需要查看注释的隔离参数@Transactional。默认是Isolation.DEFAULT(这是“...底层数据存储的默认隔离级别”)。

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:

您使用此函数的方式应确定您要为该参数提供什么值。您的saveUser(user)函数是否几乎总是与对该函数的另一个调用发生冲突?那么你可能想使用:

@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

编辑:不过,我会说它确实听起来像这样运行正常。如果你的对象在另一个线程中被修改,然后你尝试同时从另一个线程提交同一个对象,你会得到StaleObjectStateException