日期:2014-05-18 浏览次数:20546 次
create proc pr_Test 
as 
begin
     begin tran
     begin try
           
           ......
           commit tran
     end try
     begin catch
           rollback tran
     end catch
     
end
------解决方案--------------------
我一般只在分布式环境中使用set xact_abort on.
在非分布式环境我一般用事务保存点.在2005里都用try...catch.
CREATE PROCEDURE [dbo].aspnet_Vstock_Order_UserReset
    @UserId UNIQUEIDENTIFIER,
    @fMoney DECIMAL(38, 5),
    @ErrorStr VARCHAR(100) OUT
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @trancount INT
    SELECT @ErrorStr = '',  @trancount = @@TRANCOUNT
    --外部应用程序无外层事务时才启动事务,否则只使用事务保存点
    IF @trancount = 0 
        BEGIN TRAN
    ELSE
        SAVE TRAN Tran1
    BEGIN TRY
        DELETE 
        FROM   dbo.aspnet_Vstock_BuyOrder
        WHERE  UserId = @UserId
        
        DELETE 
        FROM   dbo.aspnet_Vstock_Deal
        WHERE  UserId = @UserId
        
        
        DELETE 
        FROM   dbo.aspnet_Vstock_DealHistory
        WHERE  UserId = @UserId
        
        
        DELETE 
        FROM   dbo.aspnet_Vstock_SellOrder
        WHERE  UserId = @UserId
        
        
        UPDATE dbo.aspnet_Users
        SET    Vstock_TotalMoney = @fMoney
        WHERE  UserId = @UserId
        --提交事务.若有外层事务,则提交操作交给外层事务.
        IF @trancount = 0  COMMIT
    END TRY
    BEGIN CATCH
        --若无外层事务,则回滚前面创建的事务
        IF @trancount = 0  
            ROLLBACK
        ELSE IF XACT_STATE()<>-1
            --若有外层事务,只则回滚到上一个事务保存点
            ROLLBACK TRAN tran1
        SELECT @ErrorStr = ERROR_MESSAGE()
        RAISERROR(@ErrorStr, 16, 1)
    END CATCH
    RETURN 0
END
GO