这是向sql添加事务的好方法吗?

时间:2015-12-31 10:49:35

标签: sql sql-server tsql sql-server-2012

这是将TRANSACTION添加到我的代码的好方法。我必须首先更新我的代码,如果它失败,那么插入也应该不起作用。如果这是正确的方式,请看看。如果没有,请改进。

Begin Transaction[Transaction1]

    Begin Try

         IF(@ServiceInfoToJobStatus = 1)
            Update ServiceInfo
            Set ServiceInfoToJobStatus= 0 --To set all current jobs to prior because one person cannot have many jobs selected as current
            Where @ServiceInfoToJobStatus = 1 AND ServiceInfo.fk_PersonalInfo_ServiceInfo_PID= @fk_PersonalInfo_ServiceInfo_PID

            Set @ServiceInfoEntryDateTime= (Select GetDate())

              Insert into dbo.ServiceInfo
              (

                ServiceInfoInitialDesignation,
                ServiceInfoInitialBPS,
                fk_Districts_ServiceInfo_InitialDistrictID,
                ServiceInfoJobStatus,
                ServiceInfoFromDate,
                ServiceInfoDepartment,
                fk_PersonalInfo_ServiceInfo_PID,
                ServiceInfoServiceType  ,
                ServiceInfoOffice   ,
                ServiceInfoCadre    ,
                fk_WebUsers_ServiceInfo_UserID,
                ServiceInfoEntryDateTime,
                ServiceInfoToDesignation        ,
                ServiceInfoToBPS        ,
                fk_Districts_ServiceInfo_ToDistrictID       ,
                ServiceInfoToJobStatus      ,
                ServiceInfoToDate       ,
                ServiceInfoToDepartment     ,
                ServiceInfoToServiceType        ,
                ServiceInfoToOffice     ,
                ServiceInfoToCadre      
              )

              Values 
              (

                @ServiceInfoInitialDesignation,
                @ServiceInfoInitialBPS,
                @fk_Districts_ServiceInfo_InitialDistrictID,
                @ServiceInfoJobStatus,
                @ServiceInfoFromDate,
                @ServiceInfoDepartment,
                @fk_PersonalInfo_ServiceInfo_PID,
                @ServiceInfoServiceType ,
                @ServiceInfoOffice  ,
                @ServiceInfoCadre   ,
                @fk_WebUsers_ServiceInfo_UserID,
                Convert(varchar, @ServiceInfoEntryDateTime, 113),
                @ServiceInfoToDesignation       ,
                @ServiceInfoToBPS       ,
                @fk_Districts_ServiceInfo_ToDistrictID      ,
                @ServiceInfoToJobStatus     ,
                @ServiceInfoToDate      ,
                @ServiceInfoToDepartment        ,
                @ServiceInfoToServiceType       ,
                @ServiceInfoToOffice        ,
                @ServiceInfoToCadre     
              )

              Set @ReturnStatus = 1


    Commit Transaction[Transaction1]

    End Try

    Begin Catch

              ROLLBACK Transaction[Transaction1]

              Set @ReturnStatus= 0 
              Set @ReturnStatusMessage= (Select ERROR_MESSAGE())              

    End Catch

4 个答案:

答案 0 :(得分:0)

如果代码transaction (try/catch block)updates数据输入到表中,建议使用添加inserts。在你的情况下,答案是肯定的。但是在您的事务块中,无法识别数据insert / update是否已完成。

我会使用以下语法并添加@@error

BEGIN TRY
        BEGIN TRAN   

        //YOUR CODE

         IF @@ERROR = 0
          BEGIN
              COMMIT TRAN;
          END
 END TRY
 BEGIN CATCH
        SELECT @@ERROR AS ERROR
 ROLLBACK TRAN;
 END CATCH    

答案 1 :(得分:0)

对我而言,目前还不清楚update fails的含义是什么(错误或没有更新行),但这并不重要,因为你可以很容易地测试两者:

DECLARE @UpdateErrorNo INT
DECLARE @UpdateCount INT
DECLARE @InsertErrorNo INT

Begin Transaction[Transaction1]
Begin Try
    IF(@ServiceInfoToJobStatus = 1)
        Update ServiceInfo
        Set ServiceInfoToJobStatus= 0 --To set all current jobs to prior because one person cannot have many jobs selected as current
        Where @ServiceInfoToJobStatus = 1 AND ServiceInfo.fk_PersonalInfo_ServiceInfo_PID= @fk_PersonalInfo_ServiceInfo_PID

    SET @UpdateErrorNo = @@ERROR
    SET @UpdateCount = @@ROWCOUNT

    Set @ServiceInfoEntryDateTime= (Select GetDate())

    Insert into dbo.ServiceInfo
    (
        -- skipped for readability
    )

    Values 
    (
        -- skipped for readability
    )

    SET @InsertErrorNo = @@ERROR

    Set @ReturnStatus = 1

Commit Transaction[Transaction1]

End Try

Begin Catch

    ROLLBACK Transaction[Transaction1]

    Set @ReturnStatus= 0 
    Set @ReturnStatusMessage= (Select ERROR_MESSAGE())              

End Catch

-- here you can read `@UpdateErrorNo`, `@InsertErrorNo` to check for errors

棘手的部分是@@ ERROR是在每个语句之后设置的,所以如果你有这样的情况(没有try / catch):

BEGIN TRAN
INSERT ... -- fails
UPDATE ... -- success

-- @@ERROR will not show that it is a failure
COMMIT

可能会导致意想不到的结果。

答案 2 :(得分:0)

声明@cdt datetime = getdate() 开始尝试     开始交易

Update dbo.ServiceInfo
Set ServiceInfoToJobStatus= 0 --To set all current jobs to prior because one person cannot have many jobs selected as current
Where @ServiceInfoToJobStatus = 1 
        AND fk_PersonalInfo_ServiceInfo_PID= @fk_PersonalInfo_ServiceInfo_PID

          Insert into dbo.ServiceInfo
          (

            ServiceInfoInitialDesignation,
            ServiceInfoInitialBPS,
            fk_Districts_ServiceInfo_InitialDistrictID,
            ServiceInfoJobStatus,
            ServiceInfoFromDate,
            ServiceInfoDepartment,
            fk_PersonalInfo_ServiceInfo_PID,
            ServiceInfoServiceType  ,
            ServiceInfoOffice   ,
            ServiceInfoCadre    ,
            fk_WebUsers_ServiceInfo_UserID,
            ServiceInfoEntryDateTime,
            ServiceInfoToDesignation        ,
            ServiceInfoToBPS        ,
            fk_Districts_ServiceInfo_ToDistrictID       ,
            ServiceInfoToJobStatus      ,
            ServiceInfoToDate       ,
            ServiceInfoToDepartment     ,
            ServiceInfoToServiceType        ,
            ServiceInfoToOffice     ,
            ServiceInfoToCadre      
          )

          Values 
          (

            @ServiceInfoInitialDesignation,
            @ServiceInfoInitialBPS,
            @fk_Districts_ServiceInfo_InitialDistrictID,
            @ServiceInfoJobStatus,
            @ServiceInfoFromDate,
            @ServiceInfoDepartment,
            @fk_PersonalInfo_ServiceInfo_PID,
            @ServiceInfoServiceType ,
            @ServiceInfoOffice  ,
            @ServiceInfoCadre   ,
            @fk_WebUsers_ServiceInfo_UserID,
            Convert(varchar, @cdt, 113),
            @ServiceInfoToDesignation       ,
            @ServiceInfoToBPS       ,
            @fk_Districts_ServiceInfo_ToDistrictID      ,
            @ServiceInfoToJobStatus     ,
            @ServiceInfoToDate      ,
            @ServiceInfoToDepartment        ,
            @ServiceInfoToServiceType       ,
            @ServiceInfoToOffice        ,
            @ServiceInfoToCadre     
          )

          return ...

commit transaction

结束尝试 开始捕捉     if(@@ TRANCOUNT> 0)         回滚交易

return ...

结束捕获

答案 3 :(得分:0)

这就是我使用的:

Begin Try
    Begin Tran

    -- Do your thing... some DML statements

    Commit Tran
End Try

Begin Catch
    If ( @@TranCount > 0 )
        Rollback Tran
End Catch