C++基礎——模擬事務 (1)COMMAND模式


=================================版權聲明=================================

版權聲明:原創文章 禁止轉載 

請通過右側公告中的“聯系郵箱(wlsandwho@foxmail.com)”聯系我

勿用於學術性引用。

勿用於商業出版、商業印刷、商業引用以及其他商業用途。                   

 

本文不定期修正完善。

本文鏈接:http://www.cnblogs.com/wlsandwho/p/5124027.html

恥辱牆:http://www.cnblogs.com/wlsandwho/p/4206472.html

=======================================================================

首先交代下,這樣如果這篇文章不是你想要的你就可以CTRL+W然后去找下一篇

以免你看完整篇博客都沒有了解主要功能,然后吐槽我王林森wls“什么玩意兒,還不是跟那些博客一樣沒什么用”

 

本文並不面向“Hello World”級別的讀者,該級別的讀者將浪費時間然后憤憤的關閉網頁,口中念念有詞“什么玩意兒”

本文不適合“I'm an 架構師”級別的讀者,該級別的讀者將浪費時間然后憤憤的關閉網頁,口中念念有詞“以其昏昏,使人昭昭”

本文好像只適合那些剛剛看了四人幫的書急切想要弄明白怎么使用command模式做一個事務的例子的讀者。或許還需要其他模式。

 

我王林森wlsandwho的代碼實現了:

1 簡單事務,即:全部成功提交,有一個失敗就回滾。(在本篇中講解實現)

2 嵌套事務,即:事務中的一個任務項可以是一個事務。(在下一篇中講解實現)

我王林森wlsandwho的代碼沒有實現:

1 事務保存點,即:設置保存點后,事務只會回滾到保存點的位置而不全部回滾。(在夢中講解實現:)

(包括但不限於上述內容)

 

開發環境:

Win7 64

VS 2010 SP1

Boost 1.58.0

 

“那你寫它干嘛?”

“老來多健忘,沒事寫紙上。”

=======================================================================

絕大多數的設計模式文章、資料、博客都介紹了command模式,但只涉及了文字解釋、結構圖和讓人哭笑不得的代碼。(手動斜眼)

絕大多數舉的代碼也都是些很奇怪的東西。就算看懂了,拿過來也不能用。自己從頭寫又得傻一天。(手動斜眼)

絕大多數只是在最終說了一下使用command模式能夠實現事務。(手動斜眼)

可是,你們到底是舉個能用的例子啊。可你們不舉。你們不舉啊。(手動斜眼)

只能由我來舉個例子了。

“我才看了幾眼的設計模式啊,我着急用又沒有能用的代碼”。

“怎么實現的?這什么玩意到底說的什么啊?!”。

容我張狂。我王林森wlsandwho這篇博客的問世,此處省略贊美自誇之詞一萬字。

=======================================================================

COMMAND的結構圖大家都見過,我就不畫了。

這里只畫我的事務小工具的簡單結構圖,省略N多細節。(注意,是簡單結構圖。

專業畫圖一百年。

還是畫圖工具好用啊。

=======================================================================

這里得簡要說一下各個部分。

=======================================================================

CTaskItemBase及其派生類,表示想要執行的任務。

你也可以用自己的類,這里只是舉個例子,只要那個類支持下面的函數原型:

1 bool FuncName();

當然你需要兩個,一個用來“正向操作”,一個用來“逆向操作”。

所以CTaskItemBase的接口是

1     class CTaskItemBase
2     {
3     public:
4         virtual bool Doing()=0;
5         virtual bool Undoing()=0;
6     };

例如:

你想把wlsandwho王林森的這個事務小工具用於自己的MFC對話框程序,你可以在CXXXDlg上添加bool Doing()和bool Undoing()。

然后配合命名空間中已經提供的CTransaction和CTask來完成想要的事務操作。

(我這里的CTaskItemBase、CTaskItemSample和CTaskItemSampleWithException純粹是為了舉例子做測試用的,實際使用時請換成自己的代碼。)

=======================================================================

下面該輪到CTaskBase了。

光從這張簡易圖片看,會覺得很奇怪,“CTaskBase和CTaskItemBase是關聯的,你竟然敢說‘實際使用時請換成自己的代碼’?”

是的。這也是我為什么畫了一張簡易圖,便於啟發思維。(伸手黨請將網頁拉到底復制完整代碼然后關閉本網頁。)

這得益於bind。全文的一個關鍵點就是bind。(當然還有其他的:)

使用bind,可以接受任意類型的類成員函數和對應類對象。比單純的設置回調函數,例如bool (*FuncName)(),要靈活一點。(僅針對本文說面向對象的部分。)

所以這里是可以的。

 

CTaskBase實際上是一個包裝類,用於把各種不同的任務項包裝成相同的樣子放入指定樣式的容器。Do里執行Doing,Undo里執行Undoing。

有人又要問了,那為什么不弄成仿函數或者其他的更簡單的包裝形式?

原因有很多,比方說“我不會”、“我懶”等等。然而其中一個原因有:不方便定制修改以及后續擴展。(至少我是這樣認為的。)

(另外把兩個帶着類名的類成員函數、兩個類對象寫在一行,能想象得有多長的一行嗎?分行?很難看的,而且不好意思我有強迫症。)

 

說到這個bind,很多人會想要用boost::bind。我也嘗試過。但是在MFC里用boost::bind綁定對話框類的函數,會出現下述的錯誤,我表示目前能力有限也沒心情調試。(奇怪的是控制台不會。)

c:\boost\boost_1_58_0\boost\function\function_base.hpp(318): error C2059: 語法錯誤:“reinterpret_cast”

考慮到VS2010的裝機量還是很大的,我這里用了std::bind。

(題外話:我一直用98標准,所以對於新標准和新類庫的采取的策略是:

先看看Boost里面有沒有,有就研究下,再看看標准庫里有沒有,有就替換掉Boost。

不要問我為什么,沒法解釋。主要看心情。真的。)

=======================================================================

終於說到CTransactionBase了。

CTransaction包裝了一個容器,對它遍歷執行Do,如果出錯就逆向遍歷執行Undo。

就是這么簡單。

=======================================================================

好了,解釋到這里,稍微一停頓,再從頭看一遍。

因為下面我王林森wlsandwho就要貼第一版代碼了。

(為了簡化模型、減少腦短路,所有代碼不考慮聲明/調用的時機以及拷貝效率、生存期、拷貝構造等問題。

你要問我“為什么”,我只能說為了讓你集中注意看關鍵代碼。)

=======================================================================

第一版代碼:簡單事務。

使用了Boost,無法在MFC對話框程序中使用。

示例代碼為控制台程序。

  1 #include <iostream>
  2 #include <list>
  3 #include <queue>
  4 
  5 #include <boost/shared_ptr.hpp>
  6 #include <boost/enable_shared_from_this.hpp>
  7 #include <boost/bind.hpp>
  8 #include <boost/function.hpp>
  9 
 10 namespace TransactionbyWLS
 11 {
 12     class CTaskItemBase
 13     {
 14     public:
 15         virtual bool Doing()=0;
 16         virtual bool Undoing()=0;
 17     };
 18 
 19     //////////////////////////////////////////////////////////////////////////
 20     //As a return-value of the function CommitOrAutoRollback.
 21     enum ETransRes{ EDUMMY=0,//As a virtual function's return-value Only.
 22                     ECOMMITSUCCESS=1,//All the Do-functions have done successfully.
 23                     ECOMMITFAILED_ROLLBACKSUCCESS,//One Do-function has done failed,but the functions had done have roll-backed successfully. 
 24                     ECOMMITFAILED_ROLLBACKFAILED};//One Do-function has done failed,and the functions had done have roll-backed unsuccessfully.
 25 
 26     class CTaskBase
 27     {
 28     public:
 29         typedef boost::function<bool ()> TaskCALLBACK;
 30         TaskCALLBACK m_TaskCallbackToDo;
 31         TaskCALLBACK m_TaskCallbackToUndo;
 32 
 33         bool DummyDo()
 34         {
 35             std::cerr<<"DummyDo"<<std::endl;
 36 
 37             return true;
 38         }
 39 
 40         bool DummyUnDo()
 41         {
 42             std::cerr<<"DummyDo"<<std::endl;
 43 
 44             return true;
 45         }
 46 
 47         virtual    void SetToDo(TaskCALLBACK tcbDo)
 48         {
 49             m_TaskCallbackToDo=tcbDo;
 50         }
 51 
 52         virtual void SetToUndo(TaskCALLBACK tcbToUndo)
 53         {
 54             m_TaskCallbackToUndo=tcbToUndo;
 55         }
 56 
 57         virtual bool Do()
 58         {
 59             if (m_TaskCallbackToDo)
 60             {
 61                 return m_TaskCallbackToDo();
 62             }
 63 
 64             std::cerr<<"No Operation on Do"<<std::endl;
 65 
 66             return true;
 67         }
 68 
 69         virtual bool Undo()
 70         {
 71             if (m_TaskCallbackToUndo)
 72             {
 73                 return m_TaskCallbackToUndo();
 74             }
 75 
 76             std::cerr<<"No Operation on Undo"<<std::endl;
 77 
 78             return true;
 79         }
 80     };
 81 
 82     typedef CTaskBase CTransactionTask;
 83     typedef CTaskBase* CTransactionTaskPtr;
 84 
 85     class CTransactionBase
 86     {
 87     public:
 88         virtual bool AddTask(CTransactionTask*){std::cerr << "CTransactionBase:AddTask did noting"<<std::endl;return false;}
 89         virtual ETransRes CommitOrAutoRollback(){std::cerr << "CTransactionBase:CommitOrAutoRollback did noting"<<std::endl;return EDUMMY;}
 90     };
 91 }
 92 
 93 namespace TransactionbyWLS
 94 {
 95     class CTaskItemSample:public CTaskItemBase
 96     {
 97     public:
 98         virtual bool Doing()
 99         {
100             std::cout<<"doing:"<<m_strText<<std::endl;
101 
102             return true;
103         }
104         virtual bool Undoing()
105         {
106             std::cout<<"Undoing:"<<m_strText<<std::endl;
107 
108             return true;
109         }
110 
111         void SetText(std::string strText)
112         {
113             m_strText=strText;
114         }
115 
116     protected:
117         std::string m_strText;
118     };
119 
120     class CTaskItemSampleWithException:public CTaskItemBase
121     {
122     public:
123         virtual bool Doing()
124         {
125             std::cout<<"Doing:"<<m_strText<<std::endl;
126                         
127             throw std::string("hahaha");    
128 
129             return true;
130         }
131         virtual bool Undoing()
132         {
133             std::cout<<"Undoing:"<<m_strText<<std::endl;
134 
135             return true;
136         }
137 
138         void SetText(std::string strText)
139         {
140             m_strText=strText;
141         }
142 
143     protected:
144         std::string m_strText;
145     };
146 
147     class CTask:public CTaskBase
148     {
149 
150     };
151 
152     class CTransaction:public CTransactionBase
153     {
154     public:
155         bool AddTask(CTransactionTask* poCmdPtr)
156         {
157             bool bAdding=true;
158 
159             try
160             {
161                 m_listCmdPtr.push_back(poCmdPtr);
162             }
163             catch (std::exception& e)
164             {
165                 bAdding=false;
166                 std::cerr << "exception caught: " << e.what() <<std::endl;
167             }
168             catch (...)
169             {
170                 bAdding=false;
171                 std::cerr << "Some error occurred."<<std::endl;
172             }
173 
174             return bAdding;
175         }
176 
177         void ClearAll()
178         {
179             m_listCmdPtr.clear();
180         }
181 
182         ETransRes CommitOrAutoRollback()
183         {
184             bool bDone=true;
185             bool bRollbackDone=false;
186 
187             ITListCmdPtr it;
188             for(it=m_listCmdPtr.begin();it!=m_listCmdPtr.end();++it)
189             {
190                 //Maybe we need a  try...catch but not throwing anything anymore.
191                 //So we need handle exceptions in the Member Function Do.
192                 //if (!(bDone=(*it)->Do()))
193                 //{
194                 //    break;
195                 //}
196 
197                 try
198                 {
199                     bDone=(*it)->Do();
200                 }
201                 catch (...)
202                 {
203                     bDone=false;
204                     std::cerr << "Some error occurred in the Commit part of CommitOrAutoRollback."<<std::endl;
205                 }
206 
207                 if (!bDone)
208                 {
209                     break;
210                 }
211             }
212 
213             if (!bDone)
214             {
215                 RITListCmdPtr rit(++it);
216 
217                 for (;rit!=m_listCmdPtr.rend();++rit)
218                 {
219                     //The same as above.
220                     //if (!(bRollbackDone=(*it)->UnDo()))
221                     //{
222                     //    std::cout<<"Some error occurred."<<std::endl;
223                     //
224                     //    return COMMITFAILED_ROLLBACKFAILED;
225                     //}
226 
227                     try
228                     {
229                         bRollbackDone=(*rit)->Undo();
230                     }
231                     catch (...)
232                     {
233                         bRollbackDone=false;
234                         std::cerr << "Some error occurred in the AutoRollback part of CommitOrAutoRollback."<<std::endl;
235                     }
236 
237                     if (!bRollbackDone)
238                     {
239                         return ECOMMITFAILED_ROLLBACKFAILED;
240                     }
241                 }
242 
243                 return ECOMMITFAILED_ROLLBACKSUCCESS;
244             }
245 
246             return ECOMMITSUCCESS;
247         }
248 
249     protected:
250         typedef std::list<CTransactionTask*>::iterator ITListCmdPtr;
251         typedef std::list<CTransactionTask*>::reverse_iterator RITListCmdPtr;
252 
253         typedef std::list<CTransactionTask*> ListCmdPtr;
254 
255     protected:
256         ListCmdPtr m_listCmdPtr;
257     };
258 
259 
260 }
261 
262 int main()
263 {
264     //1
265     boost::shared_ptr<TransactionbyWLS::CTaskItemSample> pTaskItem1(new TransactionbyWLS::CTaskItemSample());
266     pTaskItem1->SetText("本博客作者:王林森(wlsandwho)");
267 
268     TransactionbyWLS::CTask oTask1;
269     oTask1.SetToDo(boost::bind(&TransactionbyWLS::CTaskItemSample::Doing,pTaskItem1));
270     oTask1.m_TaskCallbackToUndo=boost::bind(&TransactionbyWLS::CTaskItemSample::Undoing,pTaskItem1);
271 
272     //2
273     boost::shared_ptr<TransactionbyWLS::CTaskItemSample> pTaskItem2(new TransactionbyWLS::CTaskItemSample());
274     pTaskItem2->SetText("作者的郵箱:wlsandwho@foxmail.com");
275 
276     TransactionbyWLS::CTask oTask2;
277     oTask2.SetToDo(boost::bind(&TransactionbyWLS::CTaskItemSample::Doing,pTaskItem2));
278     oTask2.SetToUndo(boost::bind(&TransactionbyWLS::CTaskItemSample::Undoing,pTaskItem2));
279 
280     //3
281     boost::shared_ptr<TransactionbyWLS::CTaskItemSampleWithException> pTaskItem3(new TransactionbyWLS::CTaskItemSampleWithException());
282     pTaskItem3->SetText("本博客禁止轉載");
283 
284     TransactionbyWLS::CTask oTask3;
285     oTask3.SetToDo(boost::bind(&TransactionbyWLS::CTaskItemSampleWithException::Doing,pTaskItem3));
286     oTask3.m_TaskCallbackToUndo=boost::bind(&TransactionbyWLS::CTaskItemSampleWithException::Undoing,pTaskItem3);
287 
288 
289     //
290     TransactionbyWLS::CTransaction oTransaction;
291     oTransaction.AddTask(&oTask1);
292     oTransaction.AddTask(&oTask2);
293     oTransaction.AddTask(&oTask3);
294 
295     oTransaction.CommitOrAutoRollback();
296 
297     system("pause");
298 
299     return 0;
300 }

這個版本簡要的實現了上圖模型,不能用於實際生產。(實際上本系列所有代碼均不能用於生產,但是你改改的話,還真不好說。)

所以很快有了第二版。

=======================================================================

第二版代碼:功能上未修改

移除了Boost。能夠在MFC對話框程序上跑。

  1 #pragma  once    
  2 
  3 #include <iostream>
  4 #include <list>
  5 #include <queue>
  6 #include <string>
  7 #include <functional>
  8 
  9 
 10 // #include <boost/shared_ptr.hpp>
 11 // #include <boost/enable_shared_from_this.hpp>
 12 // #include <boost/bind.hpp>
 13 // #include <boost/function.hpp>
 14 
 15 
 16 namespace TransactionbyWLS
 17 {
 18     class CTaskItemBase
 19     {
 20     public:
 21         virtual bool Doing()=0;
 22         virtual bool Undoing()=0;
 23     };
 24 
 25     //////////////////////////////////////////////////////////////////////////
 26     //As a return-value of the function CommitOrAutoRollback.
 27     enum ETransRes{    EDUMMY=0,//As a virtual function's return-value Only.
 28                     ECOMMITSUCCESS=1,//All the Do-functions have done successfully.
 29                     ECOMMITFAILED_ROLLBACKSUCCESS,//One Do-function has done failed,but the functions had done have roll-backed successfully. 
 30                     ECOMMITFAILED_ROLLBACKFAILED};//One Do-function has done failed,and the functions had done have roll-backed unsuccessfully.
 31 
 32     class CTaskBase
 33     {
 34     public:
 35         typedef std::function<bool ()> TaskCALLBACK;
 36 
 37     public:
 38         CTaskBase():m_TaskCallbackToDo(0),m_TaskCallbackToUndo(0){}
 39 
 40     protected:
 41         bool DummyDo()
 42         {
 43             std::cerr<<"DummyDo"<<std::endl;
 44 
 45             return true;
 46         }
 47 
 48         bool DummyUnDo()
 49         {
 50             std::cerr<<"DummyDo"<<std::endl;
 51 
 52             return true;
 53         }
 54     public:
 55         virtual    void SetToDo(TaskCALLBACK tcbDo)
 56         {
 57             m_TaskCallbackToDo=tcbDo;
 58         }
 59 
 60         virtual void SetToUndo(TaskCALLBACK tcbToUndo)
 61         {
 62             m_TaskCallbackToUndo=tcbToUndo;
 63         }
 64 
 65         virtual bool Do()
 66         {
 67             if (m_TaskCallbackToDo)
 68             {
 69                 return m_TaskCallbackToDo();
 70             }
 71 
 72             DummyDo();
 73 
 74             return true;
 75         }
 76 
 77         virtual bool Undo()
 78         {
 79             if (m_TaskCallbackToUndo)
 80             {
 81                 return m_TaskCallbackToUndo();
 82             }
 83 
 84             DummyUnDo();
 85 
 86             return true;
 87         }
 88 
 89     protected:
 90         TaskCALLBACK m_TaskCallbackToDo;
 91         TaskCALLBACK m_TaskCallbackToUndo;
 92     };
 93 
 94     typedef CTaskBase CTransactionTask;
 95     typedef CTaskBase* CTransactionTaskPtr;
 96 
 97     //     class CTaskBaseViaBoost
 98     //     {
 99     //     public:
100     //         //         CTaskBase():m_TaskCallbackToDo(boost::bind(&TransactionbyWLS::CTaskBase::DummyDo),_1),m_TaskCallbackToUndo(boost::bind(&TransactionbyWLS::CTaskBase::DummyUnDo),_1){}
101     //         //                                      //boost::bind(&TransactionbyWLS::CTaskItemSample::Doing,pTaskItem2)
102     //         typedef boost::function<bool ()> TaskCALLBACK;
103     //         TaskCALLBACK m_TaskCallbackToDo;
104     //         TaskCALLBACK m_TaskCallbackToUndo;
105     // 
106     //         bool DummyDo()
107     //         {
108     //             std::cerr<<"DummyDo"<<std::endl;
109     // 
110     //             return true;
111     //         }
112     // 
113     //         bool DummyUnDo()
114     //         {
115     //             std::cerr<<"DummyDo"<<std::endl;
116     // 
117     //             return true;
118     //         }
119     // 
120     //         virtual    void SetToDo(TaskCALLBACK tcbDo)
121     //         {
122     //             m_TaskCallbackToDo=tcbDo;
123     //         }
124     // 
125     //         virtual void SetToUndo(TaskCALLBACK tcbToUndo)
126     //         {
127     //             m_TaskCallbackToUndo=tcbToUndo;
128     //         }
129     // 
130     //         virtual bool Do()
131     //         {
132     //             if (m_TaskCallbackToDo)
133     //             {
134     //                 return m_TaskCallbackToDo();
135     //             }
136     // 
137     //             std::cerr<<"No Operation on Do"<<std::endl;
138     // 
139     //             return true;
140     //         }
141     // 
142     //         virtual bool Undo()
143     //         {
144     //             if (m_TaskCallbackToUndo)
145     //             {
146     //                 return m_TaskCallbackToUndo();
147     //             }
148     // 
149     //             std::cerr<<"No Operation on Undo"<<std::endl;
150     // 
151     //             return true;
152     //         }
153     //     };
154     //
155     //
156     //typedef CTaskBaseViaBoost CTransactionTask;
157     //typedef CTaskBaseViaBoost* CTransactionTaskPtr;
158 
159     class CTransactionBase
160     {
161     public:
162         virtual bool AddTask(CTransactionTask*){std::cerr << "CTransactionBase:AddTask did noting"<<std::endl;return false;}
163         virtual ETransRes CommitOrAutoRollback(){std::cerr << "CTransactionBase:CommitOrAutoRollback did noting"<<std::endl;return EDUMMY;}
164     };
165 }
166 
167 namespace TransactionbyWLS
168 {
169     class CTaskItemSample:public CTaskItemBase
170     {
171     public:
172         virtual bool Doing()
173         {
174             std::cout<<"doing:"<<m_strText<<std::endl;
175 
176             return true;
177         }
178         virtual bool Undoing()
179         {
180             std::cout<<"Undoing:"<<m_strText<<std::endl;
181 
182             return true;
183         }
184 
185         void SetText(std::string strText)
186         {
187             m_strText=strText;
188         }
189 
190     protected:
191         std::string m_strText;
192     };
193 
194     class CTaskItemSampleWithException:public CTaskItemBase
195     {
196     public:
197         virtual bool Doing()
198         {
199             std::cout<<"Doing:"<<m_strText<<std::endl;
200 
201             throw std::string("hahaha");    
202 
203             return true;
204         }
205         virtual bool Undoing()
206         {
207             std::cout<<"Undoing:"<<m_strText<<std::endl;
208 
209             return true;
210         }
211 
212         void SetText(std::string strText)
213         {
214             m_strText=strText;
215         }
216 
217     protected:
218         std::string m_strText;
219     };
220 
221     //     class CTask:public CTaskBaseViaBoost
222     //     {
223     // 
224     //     };
225 
226 
227     class CTask:public CTaskBase
228     {
229 
230     };
231 
232     class CTransaction:public CTransactionBase
233     {
234     public:
235         bool AddTask(CTransactionTask* poCmdPtr)
236         {
237             bool bAdding=true;
238 
239             try
240             {
241                 m_listCmdPtr.push_back(poCmdPtr);
242             }
243             catch (std::exception& e)
244             {
245                 bAdding=false;
246                 std::cerr << "exception caught: " << e.what() <<std::endl;
247             }
248             catch (...)
249             {
250                 bAdding=false;
251                 std::cerr << "Some error occurred."<<std::endl;
252             }
253 
254             return bAdding;
255         }
256 
257         void ClearAll()
258         {
259             m_listCmdPtr.clear();
260         }
261 
262         ETransRes CommitOrAutoRollback()
263         {
264             bool bDone=true;
265             bool bRollbackDone=false;
266 
267             ITListCmdPtr it;
268             for(it=m_listCmdPtr.begin();it!=m_listCmdPtr.end();++it)
269             {
270                 //Maybe we need a  try...catch but not throwing anything anymore.
271                 //So we need handle exceptions in the Member Function Do.
272                 //if (!(bDone=(*it)->Do()))
273                 //{
274                 //    break;
275                 //}
276 
277                 try
278                 {
279                     bDone=(*it)->Do();
280                 }
281                 catch (...)
282                 {
283                     bDone=false;
284                     std::cerr << "Some error occurred in the Commit part of CommitOrAutoRollback."<<std::endl;
285                 }
286 
287                 if (!bDone)
288                 {
289                     break;
290                 }
291             }
292 
293             if (!bDone)
294             {
295                 RITListCmdPtr rit(++it);
296 
297                 for (;rit!=m_listCmdPtr.rend();++rit)
298                 {
299                     //The same as above.
300                     //if (!(bRollbackDone=(*it)->UnDo()))
301                     //{
302                     //    std::cout<<"Some error occurred."<<std::endl;
303                     //
304                     //    return COMMITFAILED_ROLLBACKFAILED;
305                     //}
306 
307                     try
308                     {
309                         bRollbackDone=(*rit)->Undo();
310                     }
311                     catch (...)
312                     {
313                         bRollbackDone=false;
314                         std::cerr << "Some error occurred in the AutoRollback part of CommitOrAutoRollback."<<std::endl;
315                     }
316 
317                     if (!bRollbackDone)
318                     {
319                         return ECOMMITFAILED_ROLLBACKFAILED;
320                     }
321                 }
322 
323                 return ECOMMITFAILED_ROLLBACKSUCCESS;
324             }
325 
326             return ECOMMITSUCCESS;
327         }
328 
329     protected:
330         typedef std::list<CTransactionTask*>::iterator ITListCmdPtr;
331         typedef std::list<CTransactionTask*>::reverse_iterator RITListCmdPtr;
332 
333         typedef std::list<CTransactionTask*> ListCmdPtr;
334 
335     protected:
336         ListCmdPtr m_listCmdPtr;
337     };
338 }
339 
340 
341 int main()
342 {
343     TransactionbyWLS::CTaskItemSample oTaskItem1;
344     oTaskItem1.SetText("本博客作者:王林森(wlsandwho)");
345     TransactionbyWLS::CTask oTask1;
346     oTask1.SetToDo(std::bind(&TransactionbyWLS::CTaskItemSample::Doing,&oTaskItem1));
347     oTask1.SetToUndo(std::bind(&TransactionbyWLS::CTaskItemSample::Undoing,&oTaskItem1));
348 
349     TransactionbyWLS::CTaskItemSample oTaskItem2;
350     oTaskItem2.SetText("作者的郵箱:wlsandwho@foxmail.com");
351     TransactionbyWLS::CTask oTask2;
352     oTask2.SetToDo(std::bind(&TransactionbyWLS::CTaskItemSample::Doing,&oTaskItem2));
353     oTask2.SetToUndo(std::bind(&TransactionbyWLS::CTaskItemSample::Undoing,&oTaskItem2));
354 
355     TransactionbyWLS::CTaskItemSampleWithException oTaskItem3;
356     oTaskItem3.SetText("本博客禁止轉載");
357     TransactionbyWLS::CTask oTask3;
358     oTask3.SetToDo(std::bind(&TransactionbyWLS::CTaskItemSampleWithException::Doing,&oTaskItem3));
359     oTask3.SetToUndo(std::bind(&TransactionbyWLS::CTaskItemSampleWithException::Undoing,&oTaskItem3));
360 
361     TransactionbyWLS::CTransaction oTransaction;
362     oTransaction.AddTask(&oTask1);
363     oTransaction.AddTask(&oTask2);
364     oTransaction.AddTask(&oTask3);
365 
366     oTransaction.CommitOrAutoRollback();
367 
368     system("pause");
369 
370     return 0;
371 }

更改的地方不大,沒啥說的。當然也不能用於生產。作為小工具自己改改在小Demo里用一下倒是可以。

=======================================================================

還有很多坑,有空再填吧。鍵盤和桌子都好涼。(枚舉值只是為了再做擴展。)

=======================================================================

因為總是有爬蟲網站抓取我的博客,無視我的版權,我很傷心,所以文章最后只能這樣結尾。

下面開始點名:

 

Asp.net教程_mvc4_C#_Ado.net_seo_Java_HTML CSS教程
www.tzwhx.com
www.th7.cn
解決方案網
幫客之家 | IT技術 建站編程 電腦教程 www.bkjia.com
軟件開發,程序錯誤,exception
www.java123.net
一鍵重裝系統_打造智能化重裝系統軟件
www.bitscn.com


技術博客-最新最全的技術疑難解決博客
好庫文摘 - 技術改變世界
紅黑聯盟:十三年IT技術門戶 精英夢想由此起航 (網絡安全,黑客防御,信息安全,編程,系統,網絡)

 

C++基礎——模擬事務 (1)COMMAND模式

C++基礎——模擬事務 (2)COMPOSITE模式

C++基礎——模擬事務 (3)CHAIN OF RESPONSIBILITY模式

=======================================================================

(友情支持請掃描這個)

微信掃描上方二維碼捐贈


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM