插入事务 - 回滚SQL

时间:2016-05-15 12:14:53

标签: sql-server database many-to-many rollback

我是数据库的新手,我尝试创建一个存储过程,在多个关系的表中插入数据。如果操作的任何部分失败,那么它必须尽可能地从整个中恢复操作。例如,如果想要创建关于发布者和书籍的记录并成功创建发布者但是没有使用该书,那么它应该回滚 这本书的创作,而不是出版商的创作。

我的代码如下所示:

 BEGIN TRY
      BEGIN TRANSACTION
      DECLARE @serviciuKey int
      DECLARE @specializareKey int


      IF NOT EXISTS (SELECT denumire, moneda, pret FROM Serviciu where denumire=@denumire and moneda=@moneda and pret=@pret)
      BEGIN
        INSERT INTO Serviciu ( denumire, moneda, pret)
        VALUES (@denumire, @moneda, @pret)
      END
      SET @serviciuKey=@@IDENTITY
      SAVE TRANSACTION savepoint

      IF NOT EXISTS (SELECT denumire, descriere FROM Specializare where denumire=@denumire_spec AND descriere=@descriere)
      BEGIN
        INSERT INTO Specializare( denumire, descriere)
        VALUES (@denumire_spec, @descriere)
      END
      SET @specializareKey=@@IDENTITY
      SAVE TRANSACTION savepoint

      IF NOT EXISTS (SELECT * FROM Specializare_Serviciu where cod_specializare=@specializareKey and cod_serviciu=@serviciuKey)
      BEGIN
        INSERT INTO Specializare_Serviciu( cod_specializare, cod_serviciu)
        VALUES (@specializareKey, @serviciuKey)
      END
      SAVE TRANSACTION savepoint
      COMMIT TRANSACTION
   END TRY
   BEGIN CATCH
      IF @@trancount > 0 ROLLBACK TRANSACTION savepoint
      DECLARE @msg nvarchar(2048) = error_message()  
      RAISERROR (@msg, 16, 1)
      RETURN 55555
   END CATCH

当我执行该程序时,我有这个错误: 消息3931,级别16,状态1,过程AddData0,第76行 当前事务无法提交,也无法回滚到保存点。回滚整个交易。

此外,当我尝试插入一些已经存在的数据时,会插入另一个ID,这意味着IF NOT EXIST语句不起作用。

请帮忙吗?

1 个答案:

答案 0 :(得分:0)

试试这个版本:

DECLARE @serviciuKey int
DECLARE @specializareKey int

BEGIN TRY
    BEGIN TRAN

    IF NOT EXISTS (SELECT denumire, moneda, pret FROM Serviciu where denumire=@denumire and moneda=@moneda and pret=@pret)
    BEGIN
        INSERT INTO Serviciu ( denumire, moneda, pret)
        VALUES (@denumire, @moneda, @pret)
    END

    SET @serviciuKey=scope_identity()

    IF NOT EXISTS (SELECT denumire, descriere FROM Specializare where denumire=@denumire_spec AND descriere=@descriere)
    BEGIN
        INSERT INTO Specializare( denumire, descriere)
        VALUES (@denumire_spec, @descriere)
    END

    SET @specializareKey=scope_identity()

    IF NOT EXISTS (SELECT * FROM Specializare_Serviciu where cod_specializare=@specializareKey and cod_serviciu=@serviciuKey)
    BEGIN
        INSERT INTO Specializare_Serviciu( cod_specializare, cod_serviciu)
        VALUES (@specializareKey, @serviciuKey)
    END

    COMMIT TRAN
END TRY
BEGIN CATCH
    IF @@trancount > 0 
        ROLLBACK TRAN

    DECLARE @msg nvarchar(2048) = error_message()  
    RAISERROR (@msg, 16, 1)
    RETURN 55555
END CATCH