【发布时间】:2018-07-24 06:42:57
【问题描述】:
我收到此错误:
Prepare 要求命令在连接时有事务 分配给该命令的处于挂起的本地事务中。这 该命令的事务属性尚未初始化。
在 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 属性尚未初始化。
[编辑] 用例是:我有一个表我想更新并且不受回滚的影响。该表是程序正在执行的操作的日志。即使有 ROLLBACK,我也希望日志完好无损。
【问题讨论】:
-
Command2 will wait to be fully written until a Commit().如果事务中只有一个 INSERT,那么进行 显式 事务是没有价值的。 -
SqlServer 不需要命令准备;坦率地说,你可以在这里删除所有的
.Prepare()并且什么都不会改变 -
SqlServer 不需要准备但它是否受益于准备?
-
如果连接上有事务,则不指定事务就不能运行命令;你必须要么全无,要么全无
-
@MichaelPotter 以我的经验:不,不是真的 - 而且尤其是如果你是在一个你创建和执行一次的命令上这样做
标签: c# sql-server