关于spring mvc+hibernate使用OpenSessionInViewFilter导致乐观锁version失效的问题。

adsjing 发布于 2017/03/19 12:46
阅读 210
收藏 0

项目有个业务需要使用乐观锁,我在Entity里增加了@Version ,数据库表也增加了int类型的字段。
当singleSession设置为FALSE时,懒加载正常,如果version传入的值不是当前数据库的值,则抛出异常Row was updated or deleted by another transaction,这是我想要的效果,可以防止脏数据。
但是这种配置方式有2个问题:
1,相当于没有使用opensessioninviewFilter。
2,明显的增多hibernate打开的session数量,对hibernate性能影响严重。

当singleSession设置为TRUE时,无论version传入的值是什么,都能正常保存,且值为原版本号+1,这样乐观锁就失去意义了。
跟踪发现org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate
(SaveOrUpdateEvent event)方法中,
final Object entity = source.getPersistenceContext().unproxyAndReassociate( object );
event.setEntity( entity );
event.setEntry( source.getPersistenceContext().getEntry( entity ) );
event.setResultId( performSaveOrUpdate( event ) );

source.getPersistenceContext().getEntry( entity )得到的entity的version值正是数据库的version值,这导致了update的时候不会抛出异常。

请问如何在singleSession设置为TRUE时仍能实现乐观锁?或者有别的方法。

加载中
0
a
adsjing

自己写一个过滤器,继承OpenSessionInViewFilter并实现shouldNotFilter,这样乐观锁就不会失效了,但要注意OpenSessionInView会失效,即视图层的懒加载会出错。

public class MyOpenSessionInViewFilter extends OpenSessionInViewFilter{   
    @Override  
    protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
    	String url =request.getRequestURI();
    	
    	if("/test/order/saveNew".equals(url)){
    	 return true;
    	}else{
    	 return false;
    	}
    }
}  

 

返回顶部
顶部