在Workflow事務回滾中遇到了問題,是這樣的
DB2ConnectFactory 中getConn方法
/**
* 獲取數據庫連接
* @return
* @throws SQLException
*/
public Connection getConn() throws SQLException
{
Object obj = threadLocal.get();
if(obj == null)
{
this.initFactoryStack();
}else
{
connect = (Connection)obj;
}
connect.setAutoCommit(false); //事務的回滾必須建立在將Commit狀態為False下,默認是true
logger.debug("Get connect from factory - " + connect.hashCode());
return connect;
}
AbstractWorkflow 的doAction()方法
try {
//transition the workflow, if it wasn't explicitly finished, check for an implicit finish
if (!transitionWorkflow(entry, currentSteps, store, wf, action, transientVars, inputs, ps)) {
checkImplicitFinish(id);
}
} catch (WorkflowException e) {
context.setRollbackOnly(); // 這里調用WorkContext對象的setRollbackOnly()方法,執行事務的回滾
throw e;
}
GearWheelWorkFlowContext 的setRollbackOnly方法
/**
* Tranaction : Set Roll back
* @throws SQLException
*/
public void setRollbackOnly()
{
logger.debug("Context execute setRollbackOnly() !!");
Connection connect = null;
try
{
DB2ConnectFactory factory = new DB2ConnectFactory();
connect = factory.getConn();
logger.debug("Context get connect " + connect.hashCode());
if(connect != null) connect.rollback();
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
this.clostConnection(connect); //這里將關閉數據庫連接
}
}
可是這是"異常"情況下的處理流程,如果正常執行呢?
剛開始我想寫在CleanUp()方法里,但又一想不行,因為正常執行的流程需要做兩個工作
1。將Commit狀態更新為true,并提交連接
2。關閉數據庫連接
關鍵就是關閉數據庫的連接在哪里寫?!現在寫在CleanUp()不合適,因為每一個WorkStore的方法都要默認(程序已經寫死了,我可不想重載它的所有的方法!!)的關閉數據庫連接!
仔細的分析了一下,其實有兩個方法可以做到
1。編寫Proxy類
2。重載所有AbstractWorkflow中設計到事務的方法,(本來可以重載transitionWorkflow但是方法的類型卻為private?!)在它的方法下增加一個"提交"的方法。比如這樣
try {
//transition the workflow, if it wasn't explicitly finished, check for an implicit finish
if (!transitionWorkflow(entry, currentSteps, store, wf, action, transientVars, inputs, ps))
{
checkImplicitFinish(id);
}
dosubmit();
} catch (WorkflowException e) {
context.setRollbackOnly(); // 這里調用WorkContext對象的setRollbackOnly()方法,執行事務的回滾
throw e;
}
可以看到方法2比較"爛",看來下一步即使編寫方法1的實現