同事总结的hibernate意料外更新数据酷问题。

同事总结的hibernate意料外更新数据酷问题。

致action开发人员:

由于前些日子发现,从数据库中取出的Bean,被修改后,其修改的结果会重新反映到数据库中,提出下面分析和解决方法。

 

原因:

正常情况下,Service结束后,事务也就结束了。这个时候Hibernate Session就应该消失,但是,由于数据提供延迟加载

的技术支持,所以需要在Web层提供Session,用于对数据进行加载,这个时候就需要对Session的生命周期进行延长。Spring

提供了OpenSessionInViewFilter类,当一个web请求进入的时候,该请求就被分配了一个Hibernate Session到该请求的线程

上,直到该请求结束,这个时候我们通过Manager从数据库中检索一条信息到Controller层,无论在Controller层如何修改,

都不会同步到数据库中的,因为默认Session的刷新方式是AUTO(重新检索数据,提交事务,刷新数据会激活数据同步功能),

但是,通常情况下,我们对在修改后,又使用其他Manager方法对同一个Session进行了激活,使得激活了Session中的刷新事件,

这样的后果就是Hibernate把已经修改的数据作为合法的脏数据进行提交了。使得数据库中的值进行了修改。也就是说数据库

中的数据被修改了。是因为大家在同一个请求中使用了多次manager中的方法,其在最后一次使用manager方法之前,Bean中的

数据Bean进行了修改。

 

解决方法:

由于该Bean在hiberante中管理,如果瞬时化,会导致hiberante缓存中没有该数据,会重数据库中再次检索,这样即使我们

修改了也无济于事,所以现在提出一下解决方法。

 

YHB.DISABLE_SYNC(YHB中的一个常量),标记一个对象禁止与数据库中的对象同步。

当我们重数据库中检索一条信息,处于某种原因对该对象中的数据进行了修改,又不想同步到数据库中,请执行该对象的

Bean.setVersion(YHB.DISABLE_SYNC),就可以禁止该对象对数据库的修改,该方式只对自动提交更新有用,手动调用update方式无效,

后台使用该方式后还执意调用update对象,会导致版本不同步异常发生。该方式作用的对象只对不想更新的Sesstion中持久化对象

有作用,请大家确认是否必要使用。

 

例:

UkeMember member = manager.findById(1);                 // 获取一个会员

Integer version = member.getVersion();                  // 暂存会员对象的版本号,

// 如果是前台没有版本号的概念,可以忽略

member.setVersion(YHB.DISABLE_SYNC);                    // 禁止该对象内容与数据库对象同步

member.setName("hello");                                // 修改该对象中的内容

promotionRuleMng.initPromotionRules(member);            // session再次激活,该对象存活去session中。

// 数据被同步到数据库中就是它照成的。

member.setVersion(version);                             // 还原原来的版本号

Assert.assertTrue("liutie".equals(name));               // 验证或者返回

 

以上功能已经实现,请大家注意更新。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值