設計共用類別Transaction慎重使用
最近在設計一個較複雜的邏輯控制類別,因為內部較多SQL的存取所以為了方便起見,就在該類別所提供的Method當中包了Transcation,且在該Method的最後安插了一個Event(在尚未Commit之前)給使用者調用。
但這樣的設計上本身存在著一些陷阱,因為你無法預防使用者會如何使用你公開的Method,最近就遇到一個使用方式。 使用者在自己的Method內包了一層Transcation,在呼叫Component公開的Method,結果就發生了Timeout的事情,由這個經驗可以告訴我們,若再設計給其它第三者的API時,必須多考慮其它可能的使用方式。
下面的Sample大概舉例我所說的例子,請自行參考。
但這樣的設計上本身存在著一些陷阱,因為你無法預防使用者會如何使用你公開的Method,最近就遇到一個使用方式。 使用者在自己的Method內包了一層Transcation,在呼叫Component公開的Method,結果就發生了Timeout的事情,由這個經驗可以告訴我們,若再設計給其它第三者的API時,必須多考慮其它可能的使用方式。
下面的Sample大概舉例我所說的例子,請自行參考。
protected void Page_Load(object sender, EventArgs e) { try { FirstMethods(); } catch (Exception ex) { Response.Write(string.Format("Page_Load Exception :: {0}", ex.Message)); } } private void FirstMethods() { try { using (SqlConnection conn = new SqlConnection(_connString)) { conn.Open(); SqlTransaction trans = conn.BeginTransaction(); using (SqlCommand cmd = conn.CreateCommand()) { cmd.Transaction = trans; //新增第一個資料表的資料 cmd.CommandText = "insert into testFirst (id,name) values(newid(),'');"; cmd.ExecuteNonQuery(); //在Transcation尚未結束後呼叫另外一個有包Transcation的Function SecondMethods(); cmd.Transaction.Commit(); } } } catch (Exception ex) { Response.Write(string.Format("FirstMethods Exception :: {0}", ex.Message)); } } private void SecondMethods() { try { using (SqlConnection conn = new SqlConnection(_connString)) { conn.Open(); SqlTransaction trans = conn.BeginTransaction(); using (SqlCommand cmd = conn.CreateCommand()) { cmd.Transaction = trans; //讀取前一個Methods新增資料的資料表 cmd.CommandText = "select * from testFirst"; cmd.ExecuteNonQuery(); cmd.Transaction.Commit(); } } } catch (Exception ex) { Response.Write(string.Format("SecondMethods Exception :: {0}", ex.Message)); } }
留言
張貼留言
您好,我是 Lawrence,這裡是我的開發筆記的網誌,如果你對我的文章有任何疑問或者有錯誤的話,歡迎留言讓我知道。