NutTxDao简介
By:zozoh<zozohtnt@gmail.com>

NutTxDao的由来

Top

先看看Trans的优缺点

Trans.exec( () -> {
	dao.update(user);
	dao.update(role);
});

NutTxDao试图解决:

    try (NutTxDao tx = new NutTxDao(dao);) {
        tx.beginRC();
        tx.update(user);
        tx.update(role);
        tx.commit();
    } catch (Throwable e) {
    	tx.rollback();
    	log.debug("tx fail", e);
    } finally {
    	tx.close();
    }

用法

Top

NutTxDao 是NutDao的子类,通过复制NutDao的内部状态,并设置DaoRunner实例, 改变原有的事务控制逻辑

一般写法

	// 通过NutDao实例构建一下NutTxDao
	NutTxDao tx = new NutTxDao(dao);
    try {
    	// 开启事务, tx.beginRC()开启事务级别为Connection.READ_COMMITTED. 是 tx.begin(Connection.READ_COMMITTED); 的缩写.
        tx.beginRC(); 
        
        tx.update(user);
        tx.update(role);
        
        // 提交事务
        tx.commit();
    } catch (Throwable e) {
    	// 回滚事务
    	tx.rollback();
    	log.debug("tx fail", e);
    } finally {
    	// 关闭事务
    	tx.close();
    }

结合JDK7+语法

	// 通过NutDao实例构建一下NutTxDao
    try (NutTxDao tx = new NutTxDao(dao);) {
    	// 开启事务, tx.beginRC()开启事务级别为Connection.READ_COMMITTED. 是 tx.begin(Connection.READ_COMMITTED); 的缩写.
        tx.beginRC(); 
        
        tx.update(user);
        tx.update(role);
        
        // 提交事务
        tx.commit();
    } catch (Throwable e) {
    	// 回滚事务
    	tx.rollback();
    	log.debug("tx fail", e);
    }

多线程环境

Top

NutTxDao的beginX/commit/rollback/close*不是*线程安全的.

NutTxDao应该以局部变量的形式出现在代码中,而不应该是实例属性或静态属性.

创建NutTxDao自身的成本很低,相对于数据库事务来说微乎其微.

交叉事务

Top

NutTxDao的事务仅依赖于实例本身,与Trans无关,也与其他NutTxDao实例无关.

所以, 你可以同时开始多个事务, 然后按需要调用commit或rollback

NutTxDao tx1 = new NutTxDao(dao);
NutTxDao tx2 = new NutTxDao(dao);
NutTxDao tx3 = new NutTxDao(dao);
try {
	tx1.beiginRC();
	tx2.beiginRC();
	
	// 中间嵌套一个独立的事务3
	tx3.beiginRC();
	tx3.commit();
	
	tx1.commit();
	tx2.commit();
} catch (Throwable e) {
	tx1.rollback();
	tx2.rollback();
	tx3.rollback();
}

调试开关

Top

若对一个NutTxDao的事务行为有疑惑,可以开启其debug开关

NutTxDao tx1 = new NutTxDao(dao).setDebug(true);