you*_*gme 8 sql-server stored-procedures transaction
我有一个存储过程,它首先声明一些变量,然后包含begin tran;在此之后它对提供的参数执行一些验证(并且每次提供的参数验证失败时都会增加错误计数)。如果没有错误计数,则继续执行 7 次插入。在此之后,它有commit tran;
最近我在列表中添加了第 8 个插入。隐式类型转换意味着某些插入的数据在插入时会被截断。这向 SSMS 屏幕抛出了一个错误,但我发现前 7 个插入已提交,而第 8 个显然没有完成。
我很欣赏我可以包含一个try ... catch块来处理错误,但如果一个显式begin tran;不能使整个工作块自主到commit,那么有什么意义呢?我错过了什么?
我知道我也许可以将我的程序调用包装在那个级别的事务中 - 但是有人可以解释发生了什么以及为什么begin tran当包含在程序主体中时似乎不受尊重吗?如果调用该过程开始一个隐式事务,那么 proc 中的错误步骤不应该回滚受 proc 影响的所有更改 - 即使没有明确包含begin tran在 proc 主体中?
AMt*_*two 15
事务不会在出错时自动回滚——这不是它们的设计目的。它们旨在让您能够回滚。但是,您仍然需要做一些事情来实现这一点。
正如您所提到的,您可以通过 实现这一点TRY...CATCH,这使您可以最大程度地控制是否以及如何回滚。
听起来您期望 的行为SET XACT_ABORT ON,您可以在存储过程中设置它,但不是默认行为。文档中关于设置XACT_ABORTon vs off的描述是:
当 SET XACT_ABORT 为 ON 时,如果 Transact-SQL 语句引发运行时错误,则整个事务将终止并回滚。
当 SET XACT_ABORT 为 OFF 时,在某些情况下,只会回滚引发错误的 Transact-SQL 语句,并且事务继续处理。根据错误的严重程度,即使 SET XACT_ABORT 为 OFF,整个事务也可能会回滚。OFF 是 T-SQL 语句中的默认设置,而 ON 是触发器中的默认设置。
当SET XACT_ABORT是时ON,调用故障过程会在 SSMS 中返回消息,例如:
Msg 8152, Level 16, State 14, Procedure spProcName, Line 298 [Batch Start Line 5]
String or binary data would be truncated.
Completion time: 2021-04-26T10:51:00.8420902+10:00
Run Code Online (Sandbox Code Playgroud)
第一行在 SSMS 中为红色。
当SET XACT_ABORTis 时OFF,调用故障过程包括一条附加消息:
Msg 8152, Level 16, State 14, Procedure spProcName, Line 298 [Batch Start Line 5]
String or binary data would be truncated.
The statement has been terminated.
Completion time: 2021-04-26T10:53:52.5951780+10:00
Run Code Online (Sandbox Code Playgroud)
特别是,当您看到以下消息时,这意味着已提交过程中错误语句之前的语句:
The statement has been terminated.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
957 次 |
| 最近记录: |