c# - 在 SQL Server 中检测回滚
问题描述
当涉及两个或多个语句时尝试检测回滚条件。对于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
}
回滚按预期工作,但我没有得到-1
from ExecuteNonQuery
,相反,我从DELETE
操作中得到了一些受影响的行(第一条语句)
我之前确实使用SqlTransaction
过,但我正在测试基于嵌入式 SQL 的事务的行为。
解决方案
我建议您只需在CATCH
块中输入以指示错误并发生相应的回滚,而不是尝试检测ROLLBACK
自身。
SET XACT_ABORT ON;
使用 T-SQL 事务指定以确保在超时的情况下立即回滚事务是一种很好的做法。这是因为超时发生在客户端,API 取消正在运行的查询并阻止 CATCH 块的ROLLBACK
执行。然后,连接将通过打开的事务返回到池中,并且锁尚未释放。尽管当池连接被重用/重置或关闭时事务最终会被回滚,但 XACT_ABORT 设置将导致立即发生并释放资源锁。
下面是我在大多数情况下推荐的 T-SQL 事务管理和结构化错误处理模式。另外,请注意自由使用分号以避免意外。
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');
}
推荐阅读
- c# - 如何使用 Azure 媒体服务生成 Sprite 缩略图
- pytorch - 提高 Huggingface 标记器输出的速度
- html - 如何更改我的 css 以实现所需的布局?
- css - Vue组件中如何覆盖css
- r - 使用 R 计算单元格的月数、季度数和计数
- angular - 从 mat-table 中删除数据但数据不会自动刷新
- python - 如何在 Pandas 中获取 Dataframe 列的数据类型和数据长度
- python - Pandas ValueError:无法将浮点 NaN 转换为整数
- java - 如何为来自 firebase 的一个特定孩子提供参考?如何在孩子里面阅读?查看我的屏幕截图并帮助我解决此错误
- python - 在 Microsoft Graph 中获取用户个人资料图片