------------吾亦無他,唯手熟爾,謙卑若愚,好學若飢-------------
如題目所示,本小章節討論為什么SqlSession的commit會造成事物的提交
首先先看SqlSession的commit()他是一個接口的方法,所以去他的實現類找(Ctrl+H)DefaultSqlSession類中查找他的commit無參數的方法,因為我們調用的也是他的無參方法,往下看
public void commit() { this.commit(false); } public void commit(boolean force) { try { this.executor.commit(this.isCommitOrRollbackRequired(force)); this.dirty = false; } catch (Exception var6) { throw ExceptionFactory.wrapException("Error committing transaction. Cause: " + var6, var6); } finally { ErrorContext.instance().reset(); } }
看出來了嗎?他調用了他下面的一個有參數的方法,並且傳進去了參數,我們稍做記錄,force是false
dirty變成false在執行器的提交下面,說明數據不是臟的了
executor.commit(XXX)執行器的提交,我們看里面的那個方法,commit在方法參數里面調用了方法並拿到返回值,看一下那個里面的方法,注意傳進去的值為false
private boolean isCommitOrRollbackRequired(boolean force) { return !this.autoCommit && this.dirty || force; }
這個方法說實話,一眼看上去有點懵,但是你知道 ! && || 的使用優先級,你就可以計算出來了 &&>||>! 結果return回去的是true
上面的this.dirty是在上回說到的增刪改都會底層調用update方法,里面改為true的
上面的autoCommit則創建sqlSession的時候就早早的改為false,OpenSession方法底層
接下來看上面的上面的executor.commit(XXX)方法,,他是Executor執行器接口的,找他的實現類BaseExecutor類的commit的帶boolean參數的方法
public void commit(boolean required) throws SQLException { if(this.closed) { throw new ExecutorException("Cannot commit, transaction is already closed"); } else { this.clearLocalCache(); this.flushStatements(); if(required) { this.transaction.commit(); } } }
里面有一些不需要關注,不過簡單提一嘴,clearLocalCache()清理緩存,flushStatements刷新參數
最終級的關注點就是因為if中的required是傳進來的參數,上面已經解釋過是true,所以他執行下一行代碼就是transaction.commit(),哦,transaction的英文名就叫做事物
終結一句話:session.commit()最終調度到了事物的提交 ,this.transaction.commit()
