简体   繁体   English

tsql多插入带回滚的事务中

[英]tsql mutiple inserts in a transaction with rollback

I have a stored procedure when exec it, it will insert into 2 tables several records. 我在执行时有一个存储过程,它将几条记录插入2个表中。

let's say insert into author table a record and insert into book table several records(author's books). 假设将一条记录插入作者表,并将几条记录(作者的书)插入书本表。

how to make all insert in a transaction with rollback? 如何通过回滚使所有插入事务?

i read some articles/blogs, @@trancount/@@error/XACT_STATE() makes me confused. 我读了一些文章/博客,@@ trancount / @@ error / XACT_STATE()使我感到困惑。

what's the best approach? 最好的方法是什么?

here's my proc: 这是我的过程:

CREATE PROCEDURE [dbo].[proc_addAuthors]
    @bookid1 int,   @bookid2 int,   @bookid3 int,   @bookid4 int,   @bookid5 int,
    @authInfo 
AS
    insert into author...(leave out params)
    --get authorId
    ...

    --insert books (leave out validation checks...)
    insert into author2book(authorId, bookId) values(@authorid, @bookid1)
    ...

RETURN 0

If you just want to make sure that the inserts either both finishes succesfully, or both rolls back if an error occurs, you need to add the following to your stored procedure: 如果您只想确保插入都成功完成,或者在发生错误时都回滚,则需要在存储过程中添加以下内容:

CREATE PROCEDURE [dbo].[proc_addAuthors]
    @bookid1 int,   @bookid2 int,   @bookid3 int,   @bookid4 int,   @bookid5 int,
    @authInfo 
AS

SET XACT_ABORT ON;  -- Automatically rollback if an error occurs.
BEGIN TRANSACTION;  

    insert into author...(leave out params)
    --get authorId
    ...

    --insert books (leave out validation checks...)
    insert into author2book(authorId, bookId) values(@authorid, @bookid1)
    ...

COMMIT TRANSACTION;

RETURN 0
CREATE PROCEDURE addTitle(@title_id VARCHAR(6), @au_id VARCHAR(11),
                          @title VARCHAR(20), @title_type CHAR(12))
AS

BEGIN TRAN
    INSERT titles(title_id, title, type)
    VALUES (@title_id, @title, @title_type)

    IF (@@ERROR <> 0) GOTO ERR_HANDLER

    INSERT titleauthor(au_id, title_id)
    VALUES (@au_id, @title_id)

    IF (@@ERROR <> 0) GOTO ERR_HANDLER

COMMIT TRAN

RETURN 0

ERR_HANDLER:
PRINT 'Unexpected error occurred!'
ROLLBACK TRAN
RETURN 1

Here is the way to go with modern TRY CATCH block to test the error 这是使用现代的TRY CATCH块测试错误的方法

CREATE PROCEDURE [dbo].[proc_addAuthors]
    @bookid1 int,   @bookid2 int,   @bookid3 int,   @bookid4 int,   @bookid5 int,
    @authInfo 
AS
    BEGIN TRY
        BEGIN TRANSACTION
        insert into author...(leave out params)
        --get authorId
        ...

        --insert books (leave out validation checks...)
        insert into author2book(authorId, bookId) values(@authorid, @bookid1)
        ...
        COMMIT TRANSACTION
    END TRY
    BEGIN CATCH
        SELECT ERROR_MESSAGE() as errorMessage -- for example
        ROLLBACK
        RETURN 1 -- for example
    END CATCH

    RETURN 0

Using Try..Catch block gives you access to error functions, which you can use to get detailed information a about the error. 使用Try..Catch块可以访问错误功能,您可以使用这些功能获取有关错误的详细信息。

CREATE PROCEDURE [dbo].[proc_addAuthors]
@bookid1 int,   @bookid2 int,   @bookid3 int,   @bookid4 int,   @bookid5 int,
@authInfo 
AS
BEGIN
 SET NOCOUNT ON;

  DECLARE @NewAuthorID INT;


  BEGIN TRY

    BEGIN TRANSACTION
        insert into author...(leave out params)
        --get authorId
        SET @NewAuthorID = SCOPE_IDENTITY();  --<-- Get new AuthorID generated by Identity column

        --insert books (leave out validation checks...)
        insert into author2book(authorId, bookId)      --<-- use that NewAuthorID param here            
                values(@NewAuthorID, @bookid1)
        ...
    COMMIT TRANSACTION
    RETURN 0
  END TRY

  BEGIN CATCH 
      IF (@@TRANCOUNT > 0)
          ROLLBACK TRANSACTION

      DECLARE @ErrorNum int  
      SELECT @ErrorNum =  ERROR_NUMBER()
      SELECT ERROR_MESSAGE() AS ErrorMessage,
             ERROR_LINE()    AS ErrorLine, 
             --<--.... ( Other Error Functions )

      RETURN @ErrorNum
  END CATCH 
END

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM