C# 检测SQL Server中的回滚
当涉及两个或多个语句时,尝试检测回滚条件。对于C# 检测SQL Server中的回滚,c#,sql-server,transactions,ado.net,C#,Sql Server,Transactions,Ado.net,当涉及两个或多个语句时,尝试检测回滚条件。对于SqlCommand.ExecuteNonQuery方法 如果未检测到有助于计数的语句,则返回 值为-1。如果发生回滚,则返回值也是-1 我故意将-1作为引用表中具有引用完整性约束的无效项插入 string sql = $@" BEGIN TRANSACTION BEGIN TRY DELETE FROM CustomerContact WHERE CustomerId = @Id
SqlCommand.ExecuteNonQuery
方法
如果未检测到有助于计数的语句,则返回
值为-1。如果发生回滚,则返回值也是-1
我故意将-1
作为引用表中具有引用完整性约束的无效项插入
string sql = $@"
BEGIN TRANSACTION
BEGIN TRY
DELETE FROM CustomerContact WHERE CustomerId = @Id
INSERT INTO CustomerContact(CustomerId, ContactId) VALUES (3, -1)
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
END CATCH";
using (SqlCommand command = new SqlCommand(sql, connection))
{
command.Connection.Open();
command.Parameters.Add("Id", SqlDbType.Int).Value = id;
int result = command.ExecuteNonQuery();
Console.WriteLine(result); // -> returns affected deleted rows but not -1
}
回滚按预期工作,但我没有从ExecuteNonQuery
获取-1
,而是从DELETE
操作(第一条语句)获取许多受影响的行
我之前确实使用了
SqlTransaction
,但我正在测试嵌入式基于SQL的事务的行为。我建议您只插入CATCH
块来指示错误和相应的回滚发生,而不是尝试检测回滚本身
最好指定设置XACT\u ABORT ON使用T-SQL事务执行代码>以确保事务在超时时立即回滚。这是因为超时发生在客户端,在客户端,API取消正在运行的查询,并阻止执行带有回滚的CATCH块。然后,连接返回到带有打开事务的池,并且锁尚未释放。尽管当池连接被重用/重置或关闭时,事务最终将被回滚,但XACT_ABORT设置将导致立即回滚并释放资源锁
下面是我为大多数情况推荐的T-SQL事务管理和结构化错误处理模式。另外,请注意分号的广泛使用
创建一个包含这两个语句的事务并锁定,检查事务的回滚?抱歉,请您提供代码帮助。对于初学者,不要使用ExecuteOnQuery()。它只有一个非常有限的返回值。ExecuteScalar是从StoredProcess获取任何有用返回值的最小值。在一天结束的时候,函数返回值就是你想要的。如果@TRANCOUNT>0 rollback,我建议您只需插入CATCH
块以指示错误并发生回滚IF@@TRANCOUNT>0 rollback;投掷代码>。另外,添加设置XACT_ABORT ON
以确保事务在超时时立即回滚。@DanGuzman您能给我写一个答案吗?非常感谢。我是新来的。
string sql = $@"
SET XACT_ABORT ON;
BEGIN TRY
BEGIN TRANSACTION;
DELETE FROM CustomerContact WHERE CustomerId = @Id;
INSERT INTO CustomerContact(CustomerId, ContactId) VALUES (3, -1);
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
THROW;
END CATCH";
try
{
using (SqlCommand command = new SqlCommand(sql, connection))
{
command.Connection.Open();
command.Parameters.Add("Id", SqlDbType.Int).Value = id;
int result = command.ExecuteNonQuery();
Console.WriteLine(result); // -> returns affected deleted rows but not -1
}
}
catch
{
Console.WriteLine('handle exception here');
}