設計共用類別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,這裡是我的開發筆記的網誌,如果你對我的文章有任何疑問或者有錯誤的話,歡迎留言讓我知道。