SQL Server的事务回滚的错误?

我们有在SQL Server 2005上运行一些SQL的客户端应用程序,如下所示:

BEGIN TRAN; INSERT INTO myTable (myColumns ...) VALUES (myValues ...); INSERT INTO myTable (myColumns ...) VALUES (myValues ...); INSERT INTO myTable (myColumns ...) VALUES (myValues ...); COMMIT TRAN; 

它由一个长string命令发送。

如果其中一个插入失败,或者命令的任何部分失败,SQL Server是否会回滚事务? 如果它不回滚,我是否必须发送第二个命令来回滚?

我可以给出关于我正在使用的api和语言的具体信息,但是我认为SQL Server应该对任何语言都做出相应的回应。

您可以在事务之前放置set xact_abort on以确保在出错时自动回滚。

你是正确的,整个交易将被回滚。 您应该发出命令将其回滚。

您可以按如下方式将其包装在TRY CATCH块中

 BEGIN TRY BEGIN TRANSACTION INSERT INTO myTable (myColumns ...) VALUES (myValues ...); INSERT INTO myTable (myColumns ...) VALUES (myValues ...); INSERT INTO myTable (myColumns ...) VALUES (myValues ...); COMMIT TRAN -- Transaction Success! END TRY BEGIN CATCH IF @@TRANCOUNT > 0 ROLLBACK TRAN --RollBack in case of Error -- you can Raise ERROR with RAISEERROR() Statement including the details of the exception RAISERROR(ERROR_MESSAGE(), ERROR_SEVERITY(), 1) END CATCH 

从MDSN文章, 控制事务(数据库引擎) 。

如果批处理中发生运行时语句错误(例如违反约束),那么数据库引擎中的默认行为是仅回滚生成错误的语句。 您可以使用SET XACT_ABORT语句更改此行为。 执行SET XACT_ABORT ON后,任何运行时语句错误都会导致当前事务的自动回滚。 编译错误(如语法错误)不受SET XACT_ABORT的影响。 有关更多信息,请参阅SET XACT_ABORT(Transact-SQL)。

在你的情况下,它会回滚任何插入失败时的完整事务。

如果其中一个插入失败,或者命令的任何部分失败,SQL服务器是否会回滚事务?

不,不是的。

如果它不回滚,我是否必须发送第二个命令来回滚?

当然,你应该发出ROLLBACK而不是COMMIT

如果要决定是提交还是回滚事务,则应从语句中删除COMMIT语句,检查插入的结果,然后根据检查结果执行COMMITROLLBACK

这里获取与MSSQL服务器2016工作的错误信息的代码:

 BEGIN TRY BEGIN TRANSACTION -- Do your stuff that might fail here COMMIT END TRY BEGIN CATCH IF @@TRANCOUNT > 0 ROLLBACK TRAN DECLARE @ErrorMessage NVARCHAR(4000) = ERROR_MESSAGE() DECLARE @ErrorSeverity INT = ERROR_SEVERITY() DECLARE @ErrorState INT = ERROR_STATE() -- Use RAISERROR inside the CATCH block to return error -- information about the original error that caused -- execution to jump to the CATCH block. RAISERROR (@ErrorMessage, -- Message text. @ErrorSeverity, -- Severity. @ErrorState -- State. ); END CATCH