控制策略
J2EE 事务并发访问主要可以分为两类,分别是同一个系统事务和跨事务访问的并发访
问控制,其中同一个系统事务可以采取乐观锁以及悲观锁策略,而跨多个系统事务时则需
要乐观离线锁和悲观离线锁。
1、 乐观锁
乐观锁是在同一个数据库事务中经常采取的策略,因为它能使得我们的系统保持高的
性能的情况下提高很好的并发访问控制。乐观锁,顾名思义就是保持一种乐观的态度,认
为系统中的事务并发更新不会很频繁,即使冲突了也没事,大不了重新再来一次。它的基
本思想是每次提交一个事务更新时,我们想看看要修改的东西从上次读取以后有没有被其
它事务修改过,如果修改过,那么更新就会失败。
因为乐观锁其实并不会锁定任何记录,所以数据库的事务隔离级别设置为读取已提交
或者更低的隔离界别,那么是不能避免不可重复读问题的(因为此时读事务不会阻塞其它
事务),所以采用乐观锁的时候,系统应该要容许不可重复读问题的出现。
一般可以采用以下三种方法:
版本(Version)字段:在我们的实体中增加一处版本控制字段,每次事务更新后就将
版本字段的值加 1。
时间戳(timestamps):采取这种策略后,当每次要提交更新的时候就会将系统当前时
间和实体加载时的时间进行比较,如果不一致,那么就报告乐观锁失败,从而回滚事务或
者重新尝试提交。采用时间戳有一些不足,比如在集群环境下,每个节点的时间同步也许
会成为问题,并且如果并发事务间隔时间小于当前平台最小的时钟单位,那么就会发生覆
盖前一个事务结果的问题。因此一般采用版本字段比较好。
基于所有属性进行检测:采用这种策略的时候,需要比较每个字段在读取以后有没有
被修改过,所以这种策略实现起来比较麻烦,要求对每个属性进行比较,如果采用
hibernate 的话,因为 Hibernate 在一级缓存中可以进行脏检测,那么可以判断哪些字段被修
改过,从而动态的生成 SQL 语句进行更新。
在 JDBC 和 Hibernate 中使用乐观锁:
JDBC 中使用乐观锁:如果我们采用 JDBC 来实现持久层的话,那么就可以采用以上的
三种支持乐观锁的策略,在实体中增加一个 version 字段或者一个 Date 字段,也可以采用
基于所有属性的策略,下面就采用 version 字段来做一个演示:
假如系统中有一个 Account 的实体类,在 Account 中多加一个 version 字段,那么
JDBC SQL 语句如下:
Select a. version…from Account as a where (where condition)