如何在c#中使用sqltransaction

Son*_*rai 20 c# sql-server sqltransaction

我正在使用以下代码一次执行两个命令.我使用sqltransaction来确保所有命令都被执行或回滚.当我运行没有"事务"的程序时它运行正常但是当我使用"事务"时它们显示错误.我的代码如下;

SqlTransaction transaction = connectionsql.BeginTransaction();

try
{
    SqlCommand cmd1 = new SqlCommand("select account_name from master_account where NOT account_name = 'BANK' AND NOT account_name = 'LOAN'", connectionsql);
    SqlDataReader dr1 = cmd1.ExecuteReader();
    while (dr1.Read())
    {
        comboBox1.Items.Add(dr1[0].ToString().Trim());
    }
    cmd1.Dispose();
    dr1.Dispose();

    SqlCommand cmd2 = new SqlCommand("select items from rate",connectionsql);
    SqlDataReader dr2 = cmd2.ExecuteReader();
    while (dr2.Read())
    {
        comboBox2.Items.Add(dr2[0].ToString().Trim());
    }
    cmd2.Dispose();
    dr2.Dispose();
    transaction.Commit();

    dateTimePicker4.Value = dateTimePicker3.Value;
}
catch(Exception ex)
{
    transaction.Rollback();
    MessageBox.Show(ex.ToString());
}
Run Code Online (Sandbox Code Playgroud)

和错误:

在此输入图像描述

Lar*_*ech 34

您必须告诉您的SQLCommand对象使用该事务:

cmd1.Transaction = transaction;
Run Code Online (Sandbox Code Playgroud)

或者在构造函数中:

SqlCommand cmd1 = new SqlCommand("select...", connectionsql, transaction);
Run Code Online (Sandbox Code Playgroud)

确保也打开了connectionsql对象.

但你所做的只是SELECT语句.使用INSERT,UPDATE等类型操作时,事务将受益更多.


Ram*_*kar 22

以下示例创建SqlConnection和SqlTransaction.它还演示了如何使用BeginTransaction,Commit和Rollback方法.事务在任何错误时回滚,或者在没有首先提交的情况下处理它.Try/Catch错误处理用于在尝试提交或回滚事务时处理任何错误.

private static void ExecuteSqlTransaction(string connectionString)
{
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        connection.Open();

        SqlCommand command = connection.CreateCommand();
        SqlTransaction transaction;

        // Start a local transaction.
        transaction = connection.BeginTransaction("SampleTransaction");

        // Must assign both transaction object and connection 
        // to Command object for a pending local transaction
        command.Connection = connection;
        command.Transaction = transaction;

        try
        {
            command.CommandText =
                "Insert into Region (RegionID, RegionDescription) VALUES (100, 'Description')";
            command.ExecuteNonQuery();
            command.CommandText =
                "Insert into Region (RegionID, RegionDescription) VALUES (101, 'Description')";
            command.ExecuteNonQuery();

            // Attempt to commit the transaction.
            transaction.Commit();
            Console.WriteLine("Both records are written to database.");
        }
        catch (Exception ex)
        {
            Console.WriteLine("Commit Exception Type: {0}", ex.GetType());
            Console.WriteLine("  Message: {0}", ex.Message);

            // 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.
                Console.WriteLine("Rollback Exception Type: {0}", ex2.GetType());
                Console.WriteLine("  Message: {0}", ex2.Message);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请参见SqlTransaction类

  • 但是`CreateCommand`返回与连接关联的sqlcommand.那么为什么要设置sqlcommand的连接prop? (6认同)

Sna*_*yes 6

好吧,我不明白你为什么用的是交易以防万一select.

当您从数据库进行更改(添加,编辑或删除)数据时,事务非常有用.

除非您使用或声明insert,否则删除事务updatedelete

  • 我想它只是一个例子 (2认同)

Biz*_*han 6

你可以创建SqlTransaction一个SqlConnection.

并使用它来创建任意数量的 SqlCommands

SqlTransaction transaction = connection.BeginTransaction();
var cmd1 = new SqlCommand(command1Text, connection, transaction);
var cmd2 = new SqlCommand(command2Text, connection, transaction);
Run Code Online (Sandbox Code Playgroud)

要么

var cmd1 = new SqlCommand(command1Text, connection, connection.BeginTransaction());
var cmd2 = new SqlCommand(command2Text, connection, cmd1.Transaction);
Run Code Online (Sandbox Code Playgroud)

如果命令失败从不导致意外更改,请不要使用事务.

如果命令失败可能导致意外更改,则将它们放入Try/Catch块并在另一个 Try/Catch块中回滚该操作.

根据MSDN:

try/catch语句的异常处理,应始终使用回滚事务.InvalidOperationException如果连接终止或者事务已在服务器上回滚,则回滚将生成.

这是一个示例代码:

string connStr = "[connection string]";
string cmdTxt = "[t-sql command text]";

using (var conn = new SqlConnection(connStr))
{
    conn.Open();
    var cmd = new SqlCommand(cmdTxt, conn, conn.BeginTransaction());


    try
    {
        cmd.ExecuteNonQuery();
        //before this line, nothing has happened yet
        cmd.Transaction.Commit();
    }
    catch(System.Exception ex)
    {
        //You should always use a Try/Catch for transaction's rollback
        try
        {
            cmd.Transaction.Rollback();
        }
        catch(System.Exception ex2)
        {
            throw ex2;
        }
        throw ex;
    }

    conn.Close();
}
Run Code Online (Sandbox Code Playgroud)

事务被回滚在它是在事件设置之前提交或回滚调用.

因此,您无需担心应用程序被关闭.