wuguix 2008-06-18 15:53
浏览 267
已采纳

hibernate web 应用,怎么实现数据排他锁?

两个人取得同一个版本的数据,离线在web上编辑后,同时或不同时保存,我怎么保证第一个成功,第二个失败,注意是在离线状态。

我的一个办法是,把数据的版本号一同传递保存,但是没有效果。代码如下

[code="java"]

public boolean updateStatus(String ornano, int status, String userid,Integer version) {
    Material ml = this.findByOrnano(ornano);
    ml.setStatus(new Integer(status));
    ml.setLastUpdateBy(new Long(userid));
    ml.setLastUpdateDate(new Date());
    ml.setVersion(version.intValue());
    this.merge(ml);
    return true;
}

[/code]
当我设置一个比数据库版本更低的版本号,使数据过期,数据仍然能更新成功!,而且数据库的版本号也递增了。
有没有更好的办法?

  • 写回答

3条回答 默认 最新

  • llade163 2008-06-19 01:20
    关注

    给个思路,希望有所帮助。
    做个LockManager,LogManager满足以下条件:
    [list=1]
    [*]有一个[color=red]线程安全的[/color]锁队列,队列里的每个锁对象有一个ObjectClass和一个ObjectID,一个用户id,一个最近访问时间,一个默认的过期时间(多少毫秒之类)。该队列给以后台定时线程管理(可以是java.util.Timer,用new Timer(true)创建),定时清除过期锁对象(根据当前时间减去最近访问时间和过期时间比较决定)
    [*]用户ID决定该锁对象归属,锁对象可以重新进入,只要是同一个用户(业务上的真是用户),用户进入该锁之后,自动修改最近访问时间为最近时间。
    [*]LockManager类全局唯一,且线程安全,用户需要对数据库某条记录进行编辑,必须以自己的ID,ObjectClass,ObjectId向LockManager申请一把锁,当此ObjectClass以及ObjectId已经有一把锁在LockManager管理之下,判断此锁的用户和当前用户是否匹配。如果匹配,则表示用户重新进入该锁(第2点),返回true,否则返回false,外部程序得知true则显示编辑页面,false则出错页面,表示无法被编辑。
    [*]当用户完成编辑后保存,则此时LockManager根据ObjectClass和ObjectId找到该锁,如果锁是null(即被自动清除且没有其他人申请此锁),视业务严格性决定是否保存,如果可以保存,则调用持久化类进行update;如果锁不是null,则判断是否是当前用户拥有决定下一步操作,可根据业务灵活处置(比如说另存为)。因为锁有失效期,失效后其他用户就可以申请对此记录加锁。
    [/list]

    这是以前做的一个锁设计,JVM失效则失效,不适合不间断服务,如果需要不间断服务,需要放在持久化介质上,不支持群集,如果是群集则需要将锁放到共享介质上(数据库,memcache服务器之类)。特点是可以根据业务来调整策略。先验性失败,从用户体验角度更加友好,不会等到保存的时候再失败导致用户抱怨。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥170 如图所示配置eNSP
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上