简体   繁体   English

在ADO.net SQL中使用事务

[英]Using Transaction in ADO.net SQL

I am new to ADO, so I want to ask if I did right using transaction. 我是ADO的新手,所以我想问一下我是否正确使用了事务。 Here the code snippet 这里的代码片段

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;
}

For transaction, should I use 对于交易,我应该使用

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

instead of 代替

SqlCommand Com1 = new SqlCommand(SQL1, db);

because I already state begin transaction before try{} statement 因为我已经在try{}语句之前声明开始交易

EDIT: 编辑:

I get it, First syntax is applicable, but how to use ADO effectively?. 我明白了,First语法适用,但是如何有效使用ADO? I find that this way is too straightforward. 我发现这种方式太简单了。

I found myself keep doing this for inserting parameter, ex: 我发现自己继续这样做是为了插入参数,例如:

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

A lot has been happened since last year.Here I tried to simplified the answer. 自去年以来发生了很多事情。在这里,我试图简化答案。

string ConnStr = 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 conn = new SqlConnection(ConnStr))
{
    SqlTransaction transaction = null;
    try
    {
        conn.Open();
        transaction = conn.BeginTransaction();
        using (SqlCommand cmd = new SqlCommand(SQL1, conn, transaction)) { cmd.ExecuteNonQuery(); }
        using (SqlCommand cmd = new SqlCommand(SQL2, conn, transaction)) { cmd.ExecuteNonQuery(); }
        transaction.Commit();
        savestats = true;
    }
    catch (Exception ex)
    {
         // 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.
        }
    }
}

The reason why transaction is declared outside of try{} so we can rollback it in catch{} . 之所以在try{}之外声明事务,是因为我们可以在catch{}回滚它。

The downfall of this code is when error happened in conn.Open() for whatever the reason is, then attempt of transaction.Rollback() will cause exception. 这段代码的conn.Open()是,无论什么原因在conn.Open()发生错误,然后尝试进行transaction.Rollback() conn.Open() transaction.Rollback()将导致异常。

That's why another try{} catch{} added to handle it. 这就是为什么要添加另一个try{} catch{}来处理它的原因。

You should use one Command and also wrap your connection in a Using block so its properly disposed. 您应该使用一个命令,并将连接包装在“使用”块中,以便正确处理它。 Additionally, you should read from tbl_supplier after the transaction has been committed by executing a SqlDataReader . 另外,在执行事务提交后,您应该通过执行SqlDataReader从tbl_supplier中进行读取。 I'm assuming you just wanted to know how many rows were affected after the transaction committed. 我假设您只是想知道提交事务后受影响的行数。

Here is a simplified version of your code. 这是代码的简化版本。

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.
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM