2016-11-11 59 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我同意把事务放在一个使用块中会更优雅。不确定你的第二点。订单有什么问题?不遵守。 –