当前位置: 首页 > 图文教程 > Java技术 > J2EE > J2EE事务并发控制策略总结(2)(转载)

J2EE
构建高性能J2EE应用的五种核心策略
初学者如何开发出一个高质量的J2EE系统
构建高性能J2EE应用的五种核心策略
J2EE项目登录方式的改进设计与实现
开发J2EE解决方案的八个步骤(1)
开发J2EE解决方案的八个步骤(2)
J2EE架构的6个最佳实践
J2EE事务并发控制策略总结(1)(转载)
J2EE事务并发控制策略总结(2)(转载)
J2EE事务并发控制策略总结(3)(转载)
J2EE应用中常见的反模式(anti-patterns)
j2ee 常用技术
J2EE常用Jar包含义
J2EE技术之JDBC连接各种数据库的写法(给初学者)
Flex连接J2EE技术选择
用JavaScript刷新框架子页面的方法
J2EE开发原则
java获取网络图片、java截屏、java创建缩略图
jsp生成验证码
java 彻底理解 byte char short int float long double

J2EE事务并发控制策略总结(2)(转载)


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-08-14   浏览: 141 ::
收藏到网摘: n/a

下面再总结一下如何在JDBC和Hibernate中使用乐观锁:

        JDBC中使用乐观锁:如果我们采用JDBC来实现持久层的话,那么就可以采用以上将的三种支持乐观锁的策略,在实体中增加一个version字段或者一个Date字段,也可以采用基于所有属性的策略,下面就采用version字段来做一演示:

        假如系统中有一个Account的实体类,我们在Account中多加一个version字段,那么我们JDBC Sql语句将如下写:

        Select a.version....from Account as a where (where condition..)
        Update Account set version = version+1.....(another field) where version =?...(another contidition)

        这样以来我们就可以通过更新结果的行数来进行判断,如果更新结果的行数为0,那么说明实体从加载以来已经被其它事务更改了,所以就抛出自定义的乐观锁定异常(或者也可以采用Spring封装的异常体系)。具体实例如下:

.......
int rowsUpdated = statement.executeUpdate(sql);
If(rowsUpdated= =0){
throws new OptimisticLockingFailureException();
}
........

        在使用JDBC API的情况下,我们需要在每个update语句中,都要进行版本字段的更新以及判断,因此如果稍不小心就会出现版本字段没有更新的问题,相反当前的 ORM框架却为我们做好了一切,我们仅仅需要做的就是在每个实体中都增加version或者是Date字段。

        Hibernate中使用乐观锁:如果我们采用Hibernate做为持久层的框架,那么实现乐观锁将变得非常容易,因为框架会帮我们生成相应的sql语句,不仅减少了开发人员的负担,而且不容易出错。下面同样采用version字段的方式来总结一下:

        同样假如系统中有一个Account的实体类,我们在Account中多加一个version字段,

public class Account{
Long id ;
.......
@Version //也可以采用XML文件进行配置

 Int version
.......

}

        这样以来每次我们提交事务时,hibernate内部会生成相应的SQL语句将版本字段加1,并且进行相应的版本检测,如果检测到并发乐观锁定异常,那么就抛出StaleObjectStateException.

        2 悲观锁 

        所谓悲观锁,顾名思义就是采用一种悲观的态度来对待事务并发问题,我们认为系统中的并发更新会非常频繁,并且事务失败了以后重来的开销很大,这样以来,我们就需要采用真正意义上的锁来进行实现。悲观锁的基本思想就是每次一个事务读取某一条记录后,就会把这条记录锁住,这样其它的事务要想更新,必须等以前的事务提交或者回滚解除锁。

        最后我们还是需要明确一个问题,假如我们数据库事务的隔离级别设置为读取已提交或者更低,那么通过悲观锁,我们控制了不可重复读的问题,但是不能避免幻影读的问题(因为要想避免我们就需要设置数据库隔离级别为Serializable,而一般情况下我们都会采取读取已提交或者更低隔离级别,并配合乐观或者悲观锁来实现并发控制,所以幻影读问题是不能避免的,如果想避免幻影读问题,那么你只能依靠数据库的serializable隔离级别(幸运的是幻影读问题一般情况下不严重)。