2016-11-11 27 views
1

我是ADO的新手,所以我想問一下我是否正確使用事務。 下面的代碼段使用ADO.net中的事務SQL

string SQL1 = "INSERT INTO tbl_cust(cust_id,cust_name) values ('000001','YoungMcD') "; 
string SQL2 = "UPDATE tbl_cust SET custname='OldMcDonald' WHERE cust_id='000001'"; 
string SQL3 = "SELECT * FROM tbl_supplier WHERE supplier_code ='000001'"; 

// write connstring 
string conn = System.Configuration.ConfigurationManager.ConnectionStrings["connstr"].ConnectionString; 
// end of connection string 

// setting connection 
SqlConnection db = new SqlConnection(conn); 
SqlTransaction transaction1; 

db.Open(); 
transaction1 = db.BeginTransaction(); 

try 
{ 
    // insert to table 
    SqlCommand Com1 = new SqlCommand(SQL1, db, transaction1); 
    Com1.ExecuteNonQuery(); 

    SqlCommand Com2 = new SqlCommand(SQL2, db, transaction1); 
    Com2.ExecuteNonQuery(); 

    SqlCommand Com3 = new SqlCommand(SQL3, db, transaction1); 
    Com3.ExecuteNonQuery(); 

    transaction1.Commit(); 

    db.Close(); 
} 
catch 
{ 
    transaction1.Rollback(); 
    db.Close(); 
    msg = "error"; 
    goto endret; 
} 

對於事務,我應該使用

SqlCommand Com1 = new SqlCommand(SQL1, db, transaction1); 

,而不是

SqlCommand Com1 = new SqlCommand(SQL1, db); 

因爲我已經狀態之前try{}聲明

編輯開始交易:

我明白了,第一種語法是適用的,但是如何有效地使用ADO?我發現這種方式太簡單了。

我發現自己繼續這樣做插入參數,例如:

string SQL1 = "INSERT INTO tbl_cust(cust_id,cust_name) values ('" + param1 +"','"+ param2 +"') "; 
+0

您需要先使用第一個來告訴sql命令屬於哪個事務,因爲您可以同時進行多個事務。 – garethb

+0

請注意,雖然這將起作用,但實際上在應用程序和sql服務器之間進行了5次往返。使用存儲過程只需一次往返即可完成相同的操作。 –

+0

我可以要求解釋你做什麼5次往返的意思嗎?因爲我沒有得到它,爲什麼這樣做比創建存儲過程更加低劣 – KokoriNut

回答

2

您應該使用一個命令,也因此其妥善處置包裝在使用塊的連接。此外,您應該在通過執行SqlDataReader提交事務後從tbl_supplier讀取。我假設你只是想知道事務提交後有多少行受到影響。

這是您的代碼的簡化版本。

var conn = System.Configuration.ConfigurationManager.ConnectionStrings["connstr"].ConnectionString; 
string SQL1 = "INSERT INTO tbl_cust(cust_id,cust_name) values ('000001','YoungMcD') "; 
string SQL2 = "UPDATE tbl_cust SET custname='OldMcDonald' WHERE cust_id='000001'"; 

using (SqlConnection connection = new SqlConnection(conn)) 
{ 
    connection.Open(); 
    SqlTransaction sqlTran = connection.BeginTransaction(); 
    SqlCommand command = connection.CreateCommand(); 
    command.Transaction = sqlTran; 

    try 
    { 
     command.CommandText = SQL1; 
     int rowsAffected = command.ExecuteNonQuery(); 
     command.CommandText = SQL2; 
     rowsAffected += command.ExecuteNonQuery(); 
     transaction.Commit(); 
    } 
    catch (Exception ex1) 
    { 
     // Attempt to roll back the transaction. 
     try 
     { 
      transaction.Rollback(); 
     } 
     catch (Exception ex2) 
     { 
      // This catch block will handle any errors that may have occurred 
      // on the server that would cause the rollback to fail, such as 
      // a closed connection. 
     } 
    } 
} 
+0

也要刪除回滾。 – usr

+0

交易確實應該在'使用'塊中。另外,根據你的代碼的順序,我不認爲這個命令將被列入事務中。 –

+0

@ScottChamberlain我同意把事務放在一個使用塊中會更優雅。不確定你的第二點。訂單有什麼問題?不遵守。 –