网上已经有不少关于jfinal事务的文章或者贴子,可是却没有详细一点,或者说实际一点的。
java
咱们在开发中,使用事务的缘由,是由于有一系列的数据库操做须要进行,但由于某些缘由时,但愿系统可以回滚。
sql
我不清楚别人是如何使用jFinal事务的,在这里只想谈谈个人作法。同时感谢Jfinal做者的耐心解答。数据库
用例:一个Controller方法,经过它执行一系列的操做。固然它其中调用了不少方法。ui
在Action声明上添加声明事务spa
@Before(Tx.class) public void saveData(){ // 省略 }
这样,saveData就能够支持事务了,无论saveData中怎样处理,或者调用多少方法,都没问题。code
可是,在开发过程出现了一些问题。saveData中,或者所调用的方法中,若是添加了try catch,异常不可以截断它,必须继续向上抛。事务
由于Tx声明事务,是经过Tx拦截器进行的,其中Tx,经过异常对事务进行回滚。能够打开代码,以下所示,它是Tx.java中的一段。开发
try { conn = config.getConnection(); autoCommit = conn.getAutoCommit(); config.setThreadLocalConnection(conn); conn.setTransactionIsolation(getTransactionLevel(config)); // conn.setTransactionIsolation(transactionLevel); conn.setAutoCommit(false); ai.invoke(); conn.commit(); } catch (NestedTransactionHelpException e) { if (conn != null) try {conn.rollback();} catch (Exception e1) {e1.printStackTrace();} } catch (Throwable t) { if (conn != null) try {conn.rollback();} catch (Exception e1) {e1.printStackTrace();} throw new ActiveRecordException(t); }
那么当咱们使用声明式Tx事务时,想回滚只能抛出异常了。get
@Before(Tx.class) public void saveData(){ // 省略 if(xxxx){ throw new Exception("xxxxx"); } }
这样,saveData中,调用若干方法进行Db.save,Db.update,Db.delete都没问题。可是要注意事务级别it
ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin); arp.setTransactionLevel(4);
Db.save 至关于将数据库中的数据先读出来,而后再用 sql 写回去
Db.update 这类属于直接操做数据库
Db.update只须要级2就能够,可是Db.save须要级别4。
那么,除了抛出异常,在继续使用Tx声明事务的状况下,有没有不抛出进行回滚的呢?
能够这样写:
@Before(Tx.class) public void saveData(){ // 省略 if(xxxx){ // message // 略 // 手动回滚 DbKit.getConfig().getConnection().rollback(); } }