網上已經有不少關於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(); } }