事務工具在回滾時,遇到保存點停止回滾。(準確地將是指定的保存點,我不打算寫論文,差不多就行。:)要想實現上述功能,必須:……
=================================版權聲明=================================
版權聲明:原創文章 禁止轉載
請通過右側公告中的“聯繫郵箱([email protected])”聯繫我
勿用於學術性引用。
勿用於商業出版、商業印刷、商業引用以及其他商業用途。
本文不定期修正完善。
本文鏈接:http://www.cnblogs.com/wlsandwho/p/5162065.html
恥辱牆:http://www.cnblogs.com/wlsandwho/p/4206472.html
=======================================================================
事務工具在回滾時,遇到保存點停止回滾。(準確地講是指定的保存點,我不打算寫論文,差不多就行。:)
要想實現上述功能,必須:
0 保存點應當只是個標誌,不參與也不影響實際的運算。應當把它看作成一個dummy,雖然調用了,可函數體內什麼也沒有。
1 保存點要能夠像任務一樣添加到事務中。
他們應該有一致的介面用於添加到事務。
2 在回滾過程中,能夠區別保存點和普通的任務。
遇到保存點可能終止回滾,遇到任務還得繼續執行。
3 指定的保存點被添加到一個事務中,那麼指定保存點後面的任何任務不能參與回滾。
遇到了指定的保存點,我們希望得到此時的數據,不再需要繼續恢復了。
4 由於一個事務包含了一個指定保存點,所以如果這個事務被包含在另個一個事務中,那麼它後面的任何任務也不能參與回滾。
保存點可能被嵌套在多層事務里,跳出本層事務後,這個事務後的任何任務或者事務或者保存點都不因該繼續回滾。
5 執行時,能夠把外層事務指定的保存點信息傳給內層事務,使內層事務能夠判斷出當前保存點是否是指定保存點。
因為事務是可以嵌套的,指定的保存點信息可能被保存在最外的事務里,那麼它應當能夠傳遞給它的內部的事務。
我的做法:
1 引入了新類CTaskBaseEx,繼承自CTaskBase。
CTransactionBase不再從CTaskBase處,而是從CTaskBaseEx處繼承。
引入了新類CSavePointBase,它和CTransactionBase有一個共同的父類CTaskBaseEx。
這樣能夠區別出 任務和 事務、保存點。那麼就能夠在遇到指定保存點時,事務能夠停止當前回滾並且停止外層回滾。
2 CTransactionBase多了一個指向自己的關聯。
這樣事務能夠把信息傳遞給記憶體事務。責任一層層有序合理的傳達。
為什麼沒有畫在CTaskBase或者CTaskBaseEx上?因為只有事務需要這麼做,只有事務能夠包含保存點,保存點不能包含事務。
3 由於在事務中調用的任務函數必須統一,不管是保存點、任務還是事務,都得調用Do或者Undo,所以得從返回值上想辦法。還記得上一篇中我設計的枚舉值嗎?這裡用到了。
單純的true和false只能表示是否正常完成,不能表示結果值是保存點完成的還是其他的什麼完成的。可函數聲明又必須統一,介面統一,所以只能在返回值上想想辦法。
參考COM的返回值機制,我大體也做了個能用的。
(還有一些,不列舉了。看下圖自己體會吧。)
(CTaskBaseEx還繼承了一個CTagBase,後者只是存取一個內部字元串。)
簡易結構圖發生了很大的變化。(CTagBase我沒畫在簡易結構圖裡,而是單獨畫了一下。主要怕干擾視線。)