Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 这是存储过程中的良好写入事务吗_Sql Server_Tsql_Stored Procedures_Transactions_Scope - Fatal编程技术网

Sql server 这是存储过程中的良好写入事务吗

Sql server 这是存储过程中的良好写入事务吗,sql-server,tsql,stored-procedures,transactions,scope,Sql Server,Tsql,Stored Procedures,Transactions,Scope,这是我第一次使用事务,我只是想知道我是否做对了。我应该换点什么吗? 我插入后(wisp)。当插入post时,我需要在commentableEntity表中生成ID,并在wisp表中插入该ID ALTER PROCEDURE [dbo].[sp_CreateWisp] @m_UserId uniqueidentifier, @m_WispTypeId int, @m_CreatedOnDate datetime, @m_PrivacyTypeId int, @m_WispText nvarchar

这是我第一次使用事务,我只是想知道我是否做对了。我应该换点什么吗? 我插入后(wisp)。当插入post时,我需要在commentableEntity表中生成ID,并在wisp表中插入该ID

ALTER PROCEDURE [dbo].[sp_CreateWisp]
@m_UserId uniqueidentifier,
@m_WispTypeId int,
@m_CreatedOnDate datetime,
@m_PrivacyTypeId int,
@m_WispText nvarchar(200)
AS
BEGIN TRANSACTION

    DECLARE @wispId int

    INSERT INTO dbo.tbl_Wisps
    (UserId,WispTypeId,CreatedOnDate,PrivacyTypeId,WispText)
    VALUES
    (@m_UserId,@m_WispTypeId,@m_CreatedOnDate,@m_PrivacyTypeId,@m_WispText)

    if @@ERROR <> 0
        BEGIN
            ROLLBACK            
            RAISERROR ('Error in adding new wisp.', 16, 1)
            RETURN
        END

    SELECT @wispId = SCOPE_IDENTITY()

    INSERT INTO dbo.tbl_CommentableEntity
    (ItemId)
    VALUES
    (@wispId)

    if @@ERROR <> 0
        BEGIN
            ROLLBACK            
            RAISERROR ('Error in adding commentable entity.', 16, 1)
            RETURN
        END

    DECLARE @ceid int

    select @ceid = SCOPE_IDENTITY()

    UPDATE dbo.tbl_Wisps SET CommentableEntityId = @ceid WHERE WispId = @wispId

    if @@ERROR <> 0
        BEGIN
            ROLLBACK            
            RAISERROR ('Error in adding wisp commentable entity id.', 16, 1)
            RETURN
        END

COMMIT
ALTER过程[dbo]。[sp_CreateWisp]
@m_用户标识唯一标识符,
@m_WispTypeId int,
@m_CreatedOnDate日期时间,
@m_PrivacyTypeId int,
@m_WispText nvarchar(200)
作为
开始交易
声明@wispId int
插入到dbo.tbl_束中
(用户ID、WispTypeId、CreatedOnDate、PrivacyTypeId、WispText)
价值观
(@m_UserId、@m_WispTypeId、@m_CreatedOnDate、@m_PrivacyTypeId、@m_WispText)
如果@错误0
开始
回降
RAISERROR('添加新wisp时出错',16,1)
返回
结束
选择@wispId=SCOPE\u IDENTITY()
插入dbo.tbl_CommentableEntity
(项目ID)
价值观
(@wispId)
如果@错误0
开始
回降
RAISERROR('添加可注释实体时出错',16,1)
返回
结束
声明@ceid int
选择@ceid=SCOPE\u IDENTITY()
更新dbo.tbl_Wisps SET CommentableEntityId=@ceid,其中WispId=@WispId
如果@错误0
开始
回降
RAISERROR('添加wisp可注释实体id时出错',16,1)
返回
结束
犯罪
基于@gbn-answer使用try/catch:

ALTER PROCEDURE [dbo].[sp_CreateWisp]
@m_UserId uniqueidentifier,
@m_WispTypeId int,
@m_CreatedOnDate datetime,
@m_PrivacyTypeId int,
@m_WispText nvarchar(200)
AS

SET XACT_ABORT, NOCOUNT ON

DECLARE @starttrancount int

BEGIN TRY
    SELECT @starttrancount = @@TRANCOUNT

    IF @starttrancount = 0
        BEGIN TRANSACTION

        DECLARE @wispId int

        INSERT INTO dbo.tbl_Wisps
        (UserId,WispTypeId,CreatedOnDate,PrivacyTypeId,WispText)
        VALUES
        (@m_UserId,@m_WispTypeId,@m_CreatedOnDate,@m_PrivacyTypeId,@m_WispText)

        SELECT @wispId = SCOPE_IDENTITY()

        INSERT INTO dbo.tbl_CommentableEntity
        (ItemId)
        VALUES
        (@wispId)

        DECLARE @ceid int

        select @ceid = SCOPE_IDENTITY()

        UPDATE dbo.tbl_Wisps SET CommentableEntityId = @ceid WHERE WispId = @wispId

    IF @starttrancount = 0 
        COMMIT TRANSACTION
END TRY
BEGIN CATCH
    IF XACT_STATE() <> 0 AND @starttrancount = 0 
        ROLLBACK TRANSACTION
    RAISERROR ('Error in adding new wisp', 16, 1)
END CATCH
GO
ALTER过程[dbo]。[sp_CreateWisp]
@m_用户标识唯一标识符,
@m_WispTypeId int,
@m_CreatedOnDate日期时间,
@m_PrivacyTypeId int,
@m_WispText nvarchar(200)
作为
设置XACT_中止,不计数为ON
声明@starttrancount int
开始尝试
选择@starttrancount=@@TRANCOUNT
如果@starttrancount=0
开始交易
声明@wispId int
插入到dbo.tbl_束中
(用户ID、WispTypeId、CreatedOnDate、PrivacyTypeId、WispText)
价值观
(@m_UserId、@m_WispTypeId、@m_CreatedOnDate、@m_PrivacyTypeId、@m_WispText)
选择@wispId=SCOPE\u IDENTITY()
插入dbo.tbl_CommentableEntity
(项目ID)
价值观
(@wispId)
声明@ceid int
选择@ceid=SCOPE\u IDENTITY()
更新dbo.tbl_Wisps SET CommentableEntityId=@ceid,其中WispId=@WispId
如果@starttrancount=0
提交事务
结束尝试
开始捕捉
如果XACT_STATE()为0且@starttrancount=0
回滚事务
RAISERROR('添加新wisp时出错',16,1)
端接
去

自SQL Server 2005以来,您将使用TRY/CATCH+

回滚进入CATCH块,但在其他方面代码看起来不错(使用SCOPE_IDENTITY()等)。我也会使用
SET XACT\u ABORT,NOCOUNT ON

这是我的模板:

编辑:

  • 这允许按照DeveloperX的回答进行嵌套事务
  • 根据Randy的评论,该模板还允许进行更高级别的交易

我认为它不是一直都很好,但是如果您想同时使用多个存储过程,它就不好了,因为每个存储过程都独立处理事务


但在这种情况下,您应该使用try-catch块来处理异常,并防止在异常引发时打开事务。我从未认为将事务放入存储过程是一个好主意。我认为最好从更高的级别开始事务,这样可以更好地协调多个数据库(例如存储过程)调用,并将它们视为单个事务。

请参见我答案中的链接:易于嵌套是的,我的答案是关于将事务放入存储过程,在这种情况下,您的答案是正确的,那么您需要MSDTC的参与。在可能的情况下,写入的每个数据库调用都应该是原子的吗?请查看我的答案,了解如何处理它的模板。您好,我根据您的模板添加了新代码。请确认这很好,以便我可以结束此问题;)