我正在開發一些已由其他開發人員開發的系統。 在那個系統中,他們調用了一個存儲過程,用於在C#中將循環中的記錄插入到循環中,而不使用用戶定義表類型。在調用C#循環中的SQL存儲過程時處理事務
而我需要做的是將事務添加到這種情況。但問題是我不知道有交易的地方。
我想知道是否在C#代碼中翹曲循環或存儲過程中。
我正在開發一些已由其他開發人員開發的系統。 在那個系統中,他們調用了一個存儲過程,用於在C#中將循環中的記錄插入到循環中,而不使用用戶定義表類型。在調用C#循環中的SQL存儲過程時處理事務
而我需要做的是將事務添加到這種情況。但問題是我不知道有交易的地方。
我想知道是否在C#代碼中翹曲循環或存儲過程中。
你只能有它的C#循環中。在過程退出之前,在過程內啓動的事務必須提交。 SQL Server在運行過程之前和之後檢查@@TRANCOUNT
,並且如果結果不匹配,則會引發異常。所以過程不可能啓動一個必須由調用者提交的事務。
最簡單的認爲做的是包裝你的C#代碼在交易範圍:
using(var scope = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions() {
IsolationLevel = IsolationLevel.ReadCommitted
})) {
// Do the work here
scope.Complete();
}
注意,通過IsolationLevel = IsolationLevel.ReadCommitted
是critical。
在SQL Server
BEGIN TRY
BEGIN TRAN
-- DO YOUR INSERT /UPDATE /DELETE HERE
COMMIT TRAN T1
END TRY
BEGIN CATCH
-- // ROLL BACK IF ERROR OCCURS
ROLLBACK TRAN T1
END CATCH
在C#
using(TransactionScope tran = new TransactionScope()) {
// DO YOUR INSERT /UPDATE /DELETE HERE
tran.Complete();
}
在這種情況下,交易需要在C#代碼開始,您有以下選擇:
使用Transaction
從Connection object
:
using (var conn = new SqlConnection(connString))
{
conn.Open();
using (IDbTransaction tran = conn.BeginTransaction())
{
try
{
// transactional code...
using (SqlCommand cmd = conn.CreateCommand())
{
// Loop the Insert operation here
cmd.CommandText = "INSERT Operation";
cmd.Transaction = tran as SqlTransaction;
cmd.ExecuteNonQuery();
}
tran.Commit();
}
catch(Exception ex)
{
tran.Rollback();
throw;
}
}
}
Implicit or Explicit Ambient transaction
使用TransactionScope
(隱式)環境事務(例外,它是一個自動回滾)
using (var scope = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions() {
IsolationLevel = IsolationLevel.ReadCommitted
}))
{
using (var conn = new SqlConnection(connString))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
// Loop the Insert operation here
cmd.CommandText = "INSERT Operation";
cmd.ExecuteNonQuery();
}
}
scope.Complete();
}
使用CommittableTransaction
(明確的)環境事務
var tran = new CommittableTransaction();
using (var conn = new SqlConnection(connString))
{
conn.Open();
try
{
conn.EnlistTransaction(tran);
using (SqlCommand cmd = conn.CreateCommand())
{
// Loop the Insert operation here
cmd.CommandText = "INSERT Operation";
cmd.ExecuteNonQuery();
}
tran.Commit();
}
catch(Exception ex)
{
tran.Rollback();
throw;
}
}
對於Ambient transactions
,請記住,如果你打開多個連接,然後將得到local to global transaction
提升,因此要求MSDTC
並且對性能有影響。
查看以下鏈接:只有當所有的插入/ DML發生在同一個事務上下文,這是不是這裏的情況,因爲刀片是
http://www.codeproject.com/Articles/690136/All-About-TransactionScope
兩個(SQL Server中,C#)將是相同的多次往返。爲了兩者相同,它需要使用TVP –