代碼說明:
1.IMessageSink MSDN:定義消息接收器的接口。
2.主要關注SyncProcessMessage方法內的代碼,在這裡創建事務,並存儲在上下文中間,還記得上面SqlDAL的SqlTrans屬性麼,裡面就是從上下文中取得的。
3.請注意了,這裡能捕捉到錯誤,但是沒有辦法處理錯誤,所以錯誤會繼續往外拋,但是事務的完整性我們實現了。你可以在Global.asax可以做全局處理,也可以手動的try一下,但是我們不需要管理事務了,僅僅當普通的錯誤來處理了。
結束
大家可以看到,在被標注的方法裡面所有的數據庫操作都會被事務管理起來,也算是了了我心願,貌似我的Attribute做權限又看到了一絲希望了,歡迎大家多提意見:)
補充(2009-1-8)
關於在評論中提到的性能的問題,如果要使用AOP的方式來實現事務肯定比直接try catch 然後Commit 和 Rollback效率要低的,但是很明顯可維護性、使用方便性要高得多的,所以看個人需求了。這裡補充的是關於SqlDAL繼承ContextBoundObject的問題,以下是想到的解決辦法:
1.最簡單、修改UserInfoAction最少的辦法:把SqlDAL復制一份改下類名,繼承一下ContextBoundObject,然後把繼承類改一下。很不推薦: (
2.從一開始就不使用繼承方法來訪問數據層的方法,而是將SqlDAL改成一個普通類,通過聲明一個SqlDAL方式來訪問數據層:
private SqlDAL _sqlDao; public SqlDAL SqlDao { get { if (_sqlDao == null) { _sqlDao = new SqlDAL(); object obj = CallContext.GetData(TransactionAop.ContextName); if (obj != null && obj is SqlTransaction) _sqlDao.SqlTrans = obj as SqlTransaction; } return _sqlDao; } }
這樣相對於沒有加事務類僅僅多一個取值過程和判斷過程,效率應該還是比繼承SqlDAL直接繼承ContextBoundObject好很多。
個人感覺還是不是很好,繼續探索,已經想到了減少一個Attribute的辦法了,感謝歡迎大家提建議 :)