- 有一个线程安全的锁队列,队列里的每个锁对象有一个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,则判断是否是当前用户拥有决定下一步操作,可根据业务灵活处置(比如说另存为)。因为锁有失效期,失效后其他用户就可以申请对此记录加锁。
这是以前做的一个锁设计,JVM失效则失效,不适合不间断服务,如果需要不间断服务,需要放在持久化介质上,不支持群集,如果是群集则需要将锁放到共享介质上(数据库,memcache服务器之类)。特点是可以根据业务来调整策略。先验性失败,从用户体验角度更加友好,不会等到保存的时候再失败导致用户抱怨。