56
技術社區[雲棲]
Is this a MS EnterLib DAAB BUG or not?
開門見山,使用MS Enterprise Library的DAAB(Data Access Application Block)獲取數據時拋出異常。具體場景如下,通過Database對象的ExecuteReader執行兩段Select語句,前一句是不合法的,後一句是正確的。為了避免第一次執行出錯導致程序的終止,特意將其放到Try/Catch酷快中。兩次數據庫操作通過TrsanctionScope的形式納入同一個Transaction中,具體的代碼如下所示。
1: class Program
2: {
3: static void Main()
4: {
5:
6: string invalidSql = "SELECT * FROM {InvalidTable}";
7: string validSql = "SELECT * FROM {ValidTable}";
8:
9:
10: Database db = DatabaseFactory.CreateDatabase();
11: using (TransactionScope scope = new TransactionScope())
12: {
13: DbCommand commandWithInvalidSql = db.GetSqlStringCommand(invalidSql);
14: DbCommand commandWithValidSql = db.GetSqlStringCommand(validSql);
15:
16: try
17: {
18: db.ExecuteReader(commandWithInvalidSql);
19: }
20: catch
21: { }
22:
23: db.ExecuteReader(commandWithValidSql);
24: }
25: }
26: }
但是在執行第二個ExecuteReader方法的時候卻拋出如下一個InvalidOperationException(如下圖),錯誤消息為:“ExecuteReader requires an open and available Connection. The connection's current state is closed.”
原因出在這裏:在ExecuteReader中,相應的ADO.NET代碼放在try|catch中,當異常拋出後,相應的DbConnect會被關閉。但是由於在我的代碼中,兩次ExecuteReader的調用是在一個相同的Ambient Transaction中執行的,DAAB在內部采用相同的DbTransaction執行這兩項操作,當執行第一項操作時,由於出現異常導致DbConnect關閉,使用相同DbConnect的第二項操作肯定會失敗。
1: public virtual IDataReader ExecuteReader(DbCommand command)
2: {
3: ConnectionWrapper wrapper = GetOpenConnection(false);
4:
5: try
6: {
7: //
8: // JS-L: I moved the PrepareCommand inside the try because it can fail.
9: //
10: PrepareCommand(command, wrapper.Connection);
11:
12: //
13: // If there is a current transaction, we'll be using a shared connection, so we don't
14: // want to close the connection when we're done with the reader.
15: //
16: if (Transaction.Current != null)
17: return DoExecuteReader(command, CommandBehavior.Default);
18: else
19: return DoExecuteReader(command, CommandBehavior.CloseConnection);
20: }
21: catch
22: {
23: wrapper.Connection.Close();
24: throw;
25: }
26: }
27:
我不清楚微軟在設計的時候,是因為沒有考慮到這種場景呢,還是不得以而為之,或者是出於其他因素的考慮,大家有何見解。
作者:蔣金楠
微信公眾賬號:大內老A
微博:www.weibo.com/artech
如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識別二維碼)關注個人公眾號(原來公眾帳號蔣金楠的自媒體將會停用)。
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁麵明顯位置給出原文連接,否則保留追究法律責任的權利。
微信公眾賬號:大內老A
微博:www.weibo.com/artech
如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識別二維碼)關注個人公眾號(原來公眾帳號蔣金楠的自媒體將會停用)。
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁麵明顯位置給出原文連接,否則保留追究法律責任的權利。
最後更新:2017-10-30 14:35:02