日期:2014-05-16  浏览次数:20447 次

Nutz的 数据库事务

鄙人原本打算对nutz做一个顺序的介绍,zozoh知道后就说:“你这么做不是很有必要,因为用户不如去看wiki,refrence 或者 manual ”。你怎么想呢? 我觉得他说的有道理,于是决定按照乱针绣(一种刺绣针法)的方式来介绍,和大家来交流对nutz的使用和看法。

1.数据库事务
?数据库的事务是作为单个逻辑工作单元执行的一系列操作。一个逻辑工作单元必须有四个属性,称为原子性、一致性、隔离性和持久性 (ACID) 属性,只有这样才能成为一个事务。一般来讲,隔离性是通过锁机制来实现,而其他三个特性通过日志机制实现。
?当一个数据库的某些数据由多个客户端并发访问操作的时候,可能会出现一系列的问题:(1)脏读(dirty read),(2)不可重复读(unrepeatable read),(3)幻象读(phantom read),(4)丢失更新

2.使用Nutz来处理事务
?在nutz中使用一个类org.nutz.trans.Trans来处理事务,使用方式如下:

  //TODO 选择事务级别 
  int level=Connection.TRANSACTION_SERIALIZABLE;
  Trans.exec(level, new Atom(){
   @Override
   public void run() {
    //TODO 事务内的操作逻辑
   }   
  });

???
??当然你也可是使用如下默认方式:

  Trans.exec(new Atom(){
   @Override
   public void run() {
    //TODO 
   }
  });

?
??在这种情况下,level默认是Connection.TRANSACTION_READ_COMMITTED
??注:如果你使用jdbc来直接操作事务,当然你可以在某一个位置设置保存点,如果事务失败,可以回滚到那个点,在nutz中整个事务要么成功,要么失败,全部回滚。如果你希望使用savepoint改怎么办呢,你可以这么用:

  Dao dao=null;
  dao.run(new ConnCallback(){
   @Override
   public void invoke(Connection conn) throws Exception {
    // TODO 在这里面使用Connection来操作   
   }   
  });

??
??Nutz没有提供其他的接口给用户设置SavePoint,当您使用的时候如果有这种需求,那么请告诉我或者直接给nutz报Bug.
??
????
3.ThreadLocal
?Nutz在实现Trans这个类的时候用到了ThreadLcoal(方便了使用者存储变量到当前线程。),用来存储用户的每一次事务动作。具体实现请参见源代码类org.nutz.trans.Trans。?
?

参考文档:

(1)http://www.iteye.com/topic/103804?page=1

(2)http://hi.baidu.com/splendor518/blog/item/59ea983089567593a8018e34.html

1 楼 lovemylover 2009-12-30  
这种写法真的很不爽,当用习惯了Spring的事务处理方式之后,我再也不愿意手动开启Transaction
2 楼 amosleaf 2010-01-04  
@lovemylover:仅仅是写法原因?还是有其他原因,原闻其详。
3 楼 nwangwei 2010-01-10  
Trans.exec(level, new Atom(){  
@Override 
public void run() {  
  //TODO 事务内的操作逻辑  
}     
});

我觉得可能是匿名类的缘故,很多人不适应这种使用方法。根本的解决方法还是改变Java的语法,呵呵,比如把Function当作一等公民。
4 楼 cosmo1987 2012-02-14  
那如果rollback失败了抛出SQLException异常,捕获后应该如何处理呢?
5 楼 hhxyjsj 2012-06-16  
是不是应该为事务加一个返回值,要么执行的成不成功都不清楚!