准备要求命令进行交易

时间:2018-07-23 21:41:50

标签: c# sql-server

我收到此错误:

  

准备要求连接时命令具有事务   分配给命令的命令处于未决的本地事务中。的   该命令的事务属性尚未初始化。

关于Prepare():

connection = new SqlConnection(dbconnectionstring);
connection.Open();
transaction = connection.BeginTransaction();
SqlCommand Command1 = GetCommand1(connection);
SqlCommand Command2 = GetCommand2(connection, transaction);


private SqlCommand GetCommand1(SqlConnection connection)
{
    const string sql = @"
        INSERT INTO R_Activity(start_time, activity_num) OUTPUT INSERTED.ID VALUES(SYSDATETIME(), @ACTIVITY_NUM)
        ";
    SqlCommand command = new SqlCommand(sql, connection);
    command.Parameters.Add(new SqlParameter("@ACTIVITY_NUM", System.Data.SqlDbType.Int, 0));
    command.Prepare();  // Error here.
    return command;
}


private SqlCommand GetCommand2(SqlConnection connection, SqlTransaction transaction)
{
    const string sql = @"
        INSERT IVS_RUNHISTORY ( r_activity_id, datasource,  rundate)
                               OUTPUT INSERTED.ID
                               VALUES (@r_activity_id, @datasource, @rundate)
        ";
    SqlCommand command = new SqlCommand(sql, connection, transaction);

    command.Parameters.Add(new SqlParameter("@datasource", System.Data.SqlDbType.Char, 4));
    command.Parameters.Add(new SqlParameter("@rundate", System.Data.SqlDbType.DateTime, 0));
    command.Parameters.Add(new SqlParameter("@r_activity_id", System.Data.SqlDbType.Int, 0));
    command.Prepare();
    return command;
}

如何避免该错误?

我的目标是允许Command1在事务外部运行,以便在插入运行后立即将行完全写入数据库,而Command2将等待被完全写入,直到Commit()。

命令的区别在于Command1就像正在发生的事情的日志,而Command2则是控制台程序的业务逻辑。也就是说,即使业务逻辑失败,我仍然希望在数据库中查看日志。

这是代码的简化示例。还有其他与交易相关的命令。

[编辑] 如果我注释掉Prepare(),则错误会移动执行:

  

ExecuteScalar要求命令在   分配给命令的连接处于未决的本地事务中。   该命令的Transaction属性尚未初始化。

[编辑] 这样的用例是:我有一个要更新的表,并且不进行回滚。该表是程序正在执行的日志。我希望即使有回滚,日志也能保持完整。

1 个答案:

答案 0 :(得分:0)

我通过为基于事务的SQL打开第二个连接来解决了这个问题。

[评论告诉我我疯了快乐地接受了]

connection = new SqlConnection(dbconnectionstring);
connection.Open();
connectiont = new SqlConnection(dbconnectionstring);
connectiont.Open();
transaction = connectiont.BeginTransaction();
SqlCommand Command1 = GetCommand1(connection);
SqlCommand Command2 = GetCommand2(connectiont, transaction);


private SqlCommand GetCommand1(SqlConnection connection)
{
    const string sql = @"
        INSERT INTO R_Activity(start_time, activity_num) OUTPUT INSERTED.ID VALUES(SYSDATETIME(), @ACTIVITY_NUM)
        ";
    SqlCommand command = new SqlCommand(sql, connection);
    command.Parameters.Add(new SqlParameter("@ACTIVITY_NUM", System.Data.SqlDbType.Int, 0));
    command.Prepare();  // Error here.
    return command;
}


private SqlCommand GetCommand2(SqlConnection connection, SqlTransaction transaction)
{
    const string sql = @"
        INSERT IVS_RUNHISTORY ( r_activity_id, datasource,  rundate)
                               OUTPUT INSERTED.ID
                               VALUES (@r_activity_id, @datasource, @rundate)
        ";
    SqlCommand command = new SqlCommand(sql, connection, transaction);

    command.Parameters.Add(new SqlParameter("@datasource", System.Data.SqlDbType.Char, 4));
    command.Parameters.Add(new SqlParameter("@rundate", System.Data.SqlDbType.DateTime, 0));
    command.Parameters.Add(new SqlParameter("@r_activity_id", System.Data.SqlDbType.Int, 0));
    command.Prepare();
    return command;
}