spring hibernate乐观锁定问题

时间:2013-12-02 09:20:27

标签: java spring hibernate transactions spring-transactions

这是我的存储库层:

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);
    }
}

这是我的服务层:

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);
    }   
}

这里我以异步方式访问和更新对象:

class SomeClass{
    @Autowired
    Service service;    
    public void asynchronousSaveOrUpdate(){
        User u = service.findUserbyId(1);
        service.saveUser(1);
    }
    public void asynchronousfindUsersById(){
        service.findUserbyId(1);
    }
}

我遇到了这个例外:

[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)

注意:我不希望Transactional用于ServiceImpl.findUserById()方法。

执行@Transactional(readOnly =true)@Transactional(propagation =Propagation.REQUIRES_NEW)会解决此问题吗?

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

1 个答案:

答案 0 :(得分:4)

您必须提供有关正在发生的事情的更多信息。每次保存用户时是出现此错误,还是仅在您从多个线程同时调用saveUser(user)时发生此错误?或者,只要您拨打findUserById()saveUser()

,就会发生这种情况

您可能希望查看@Transactional注释的Isolation参数。默认值为Isolation.DEFAULT(这是“基础数据存储区的默认隔离级别”)。

您使用此功能的方式应确定您要为此参数提供的值。你的saveUser(user)函数几乎总是与另一个函数调用冲突吗?然后你可能想要使用:

@Transactional(isolation = Isolation.READ_COMMITTED)

编辑:我会说它确实听起来像是在运作正常。有意义的是,如果你的对象在另一个线程中被修改,然后你试图同时从另一个线程提交同一个对象,你会得到StaleObjectStateException