日期:2014-05-19  浏览次数:20745 次

J2EE 事务总结
  1. 数据库事务

    数据库的事务级别:

    1)读取未提交(read uncommitted)
    最低的事务隔离级别,读事务不会堵塞读事务,写事务不会堵塞读事务,但是会堵塞写事务。会造成脏读

    2)读取已提交(read committed)
    写事务会堵塞写事务和读事务,但是读事务不会堵塞写事务和读事务。因为写事务堵塞读事务,所以不会造
    脏读。但是因为读事务不会堵塞写事务,如果读取事务时,有写事务在进行,会造成前后读取数据不一致,
    就是所谓的 不可重复读

    3)可重复读(repeatable read)
    写事务会堵塞写事务和读事务,读事务会堵塞写事务,但是读事务不会堵塞读事务。不会造成 不可重复读
    但是会造成幻读。(事务A读取与搜索条件相匹配的若干行。事务B以插入或删除行等方式来修改事务A的结果集,然后再提交。如果事务A重复该读取操作,则将获得不同的行集。采用这种方式所添加的行叫做幻影行 )

    4)序列化(serializale)
    最严格的事务级别。不会造成脏读、不可重复读、幻读。但是会极大的影响系统性能,因此应该避免设置成序列化,而
    应该采用较低的隔离级别,然后采用并发控制策略来进行事务的并发访问控制。
  2. JTA事务
  3. Spring事务
    http://vae.iteye.com/blog/476457
  4. 事务并发访问策略

    1)同一系统事务
    ?
    a.乐观锁
    ???? 认为系统中的事务并发更新不会很频繁。每次提交一个事务更新,如果发现数据被其他事务修改过,则修改失败。
    实现方法:
    Ⅰ.版本(version)字段:
    在实体中增加一个版本控制字段,每次事务更新后就将版本字段的值加1。
    example:
    ???? JDBC中实现:
    ????
    Select a.version....from Account as a where (where condition..)
    
      Update Account set version = version+1.....(another field) where version =?...(another contidition)
    ?? 如果update的更新结果的行数为0,说明实体从加载以来已经被其他事务修改过,会抛出自定义的乐观锁
    ? 异常。
    ?
    .......
    
      int rowsUpdated = statement.executeUpdate(sql);
    
      If(rowsUpdated= =0){
    
      throws new OptimisticLockingFailureException();
    
      }
    
      ........
    ?? hibernate 实现悲观锁:
    ??
    在实体类中加一个version字段
    public class Account{
    
      Long id ;
    
      .......
    
      @Version //也可以采用XML文件进行配置
    
      Int version
    
      .......
    
      }
    ?Ⅱ.时间戳(timestamps):
    每次要提交更新时将系统当前时间和实体加载时间进行比较,如果不一致,就会报告乐观锁失败,
    从而回滚或重新尝试提价。缺点就是,当并发事务时间间隔小于当前系统平台的最小时间单位时,
    会发生覆盖前一个事务结果的问题。
    基于所有属性进行检测:
    比较每个字段在读取后有没有被修改过。
    b.悲观锁
    认为系统中的并发更新会很频繁,并且事务失败了重来的开销很大。每次一个事务读取某一条记录,
    就会把这条记录锁住,这样其他事务要想更新,必须等以前的事务提交或者回滚解除锁。可以控制
    不可重复读的问题,但是无法避免幻读
    ?example:
    JDBC中使用悲观锁:
    Select * from Account where ...(where condition).. for update.
    ?Hibernate实现悲观锁:
    ?
     .......
    
      session.lock(account, LockMode.UPGRADE);
    
      ......
    ?或者可以采用如下方法加载对象:
    session.get(Account.class,identity,LockMode.UPGRADE).
    ?
    2)跨系统事务
1 楼 mingyang2013 2011-09-15  
"写事务会堵塞写事务和读事务":请问一下,一个事务通常包含一些列操作,可能是读,可能是写,也可能是读和写,怎么规定或判定这个事务是“读”事务还是“写”事务呢?