sql-server – 事务是否需要try catch?

我是一名c#开发人员,学习更多Tsql.我写了一个这样的脚本:
begin transaction
--Insert into several tables
end transaction

但我被告知这不是一个好主意,并使用这样的东西:

BEGIN TRANSACTION;

BEGIN TRY
    -- Generate a constraint violation error.
    DELETE FROM Production.Product
    WHERE ProductID = 980;
END TRY
BEGIN CATCH
    SELECT 
        ERROR_NUMBER() AS ErrorNumber,ERROR_SEVERITY() AS ErrorSeverity,ERROR_STATE() AS ErrorState,ERROR_PROCEDURE() AS ErrorProcedure,ERROR_LINE() AS ErrorLine,ERROR_MESSAGE() AS ErrorMessage;

    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION;
END CATCH;

IF @@TRANCOUNT > 0
    COMMIT TRANSACTION;
GO

我不明白为什么第二个例子更正确.第一个不会以同样的方式工作吗?似乎第一个要么更新所有表,要么根本不更新?我不明白为什么在提交之前检查@@ TRANCOUNT是必要的.

解决方法

只有在try块内部并且在实际语句之前才打开一个事务,并且直接提交它,不要等待你的控制转到批处理结束以提交事务.

一旦你进入Try Block并且你已经打开了一个事务,如果出现问题控件将跳转到CATCH块,只需在那里回滚你的事务并根据需要进行其他错误处理.

在使用@@ ROWCOUNT函数实际回滚事务检查任何打开的事务之前,我添加了一点检查,它在这种情况下确实没有多大意义.在你打开一个事务之前在你的try块中做一些验证检查更有用,比如检查参数值和其他东西,如果任何验证检查失败,在try块中引发错误,那么控制将跳转到catch块甚至没有在那里打开交易,你可以检查任何打开的交易和回滚,如果有任何打开的交易.在你的情况下,你真的不需要检查任何打开的交易,因为你不会进入catch块,除非你的交易中出现问题.

BEGIN TRY

  BEGIN TRANSACTION 
     -- Multiple Inserts
    INSERT INTO....
    INSERT INTO.... 
    INSERT INTO.... 
 COMMIT TRANSACTION 
    PRINT 'Rows inserted successfully...'

END TRY

BEGIN CATCH 
  IF (@@TRANCOUNT > 0)
   BEGIN
      ROLLBACK TRANSACTION 
      PRINT 'Error detected,all changes reversed'
   END 
    SELECT
        ERROR_NUMBER() AS ErrorNumber,ERROR_MESSAGE() AS ErrorMessage
END CATCH

相关文章

(一)日志传送架构 (1.1)相关服务器 主服务器 :用于生产的服务器,上面运行这生产SQL Server数据库...
(一)事故背景 最近在SQL Server 2012生产数据库上配置完事物复制(发布订阅)后,生产数据库业务出现了...
(一)测试目的 目前公司使用的SQL SERVER 2012高可用环境为主备模式,其中主库可执行读写操作,备库既...
(一)背景个人在使用sql server时,用到了sql server的发布订阅来做主从同步,类似MySQL的异步复制。在...
UNION和OR谓词 找出 product 和 product2 中售价高于 500 的商品的基本信息. select * from product wh...
datawhale组队学习task03