3

我有一些“基本操作”存储过程,比如BookAVehicleUnBookAVehicle. 他们都在交易中。

但是现在我需要一个更复杂的存储过程:RescheduleBooking. 它还需要是事务性的。

现在,ResceduleBooking我想从内部调用BookAVehicle,在这种情况下,我不希望内部事务回滚。

但是当我BookAVehicle直接调用时,我想保持回滚。

关于如何优雅地做到这一点的任何建议?

我在想一些类似于“包装”存储过程的东西,它作为参数采用存储过程的名称,并且只包含一个事务和对参数存储过程的调用。

因此,当我“直接”调用它时,我会调用:

TransactionWrapper(BookAVehicleWithoutTrans)

当我从另一个事务中调用它时,我调用:

RescheduleBooking -> BookAVehicleWithoutTrans
4

1 回答 1

1

当您执行 BEGIN TRANSACTION 时,内部计数器会增加 @@TRANCOUNT。ROLLBACK TRANSACTION 会将所有 BEGIN TRANSACTIONS 设置 @@TRANCOUNT 回滚为 0。执行提交事务只会减少 @@TRANCOUNT,当 @@TRANCOUNT 为 1 时,它将执行完整提交,然后将其设置为 0。

考虑到这一点,假设您在 Book 和 UnBook 程序中配对了 BEGIN 和 COMMIT TRANSACTIONS,我将执行类似以下的 RescheduleBooking 程序,即使取消预订失败,也会保留第一本书......

CREATE PROCEDURE RescheduleBooking ...
AS
BEGIN
      BEGIN TRY
         BEGIN TRANSACTION
         EXEC BookAVehicle ...
         COMMIT TRANSACTION
      END TRY
      BEGIN CATCH
         IF @@TRANCOUNT > 0
         BEGIN
             ROLLBACK TRANSACTION
         END
         RETURN
      END CATCH;

   -- If the unbook fails the booking above will still stay.
      BEGIN TRY
         BEGIN TRANSACTION
         EXEC UnBookAVehicle ...
         COMMIT TRANSACTION
      END TRY
      BEGIN CATCH
         IF @@TRANCOUNT > 0
         BEGIN
             ROLLBACK TRANSACTION
         END
         RETURN
      END CATCH;
END
于 2014-05-23T13:45:27.440 回答