Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Zagnieżdżone procedury składowane zawierające wzorzec TRY CATCH ROLLBACK?

To jest nasz szablon (usunięto rejestrowanie błędów)

Jest przeznaczony do obsługi

Wyjaśnienia:

  • wszystkie TXN zaczynają się i zatwierdzają/wycofują muszą być sparowane, aby @@TRANCOUNT jest taki sam przy wejściu i wyjściu

  • niezgodności @@TRANCOUNT spowodować błąd 266, ponieważ

    • BEGIN TRAN zwiększa @@TRANCOUNT

    • COMMIT zmniejsza @@TRANCOUNT

    • ROLLBACK zwraca @@TRANCOUNT do zera

  • Nie możesz zmniejszyć @@TRANCOUNT dla bieżącego zakresu
    To według Ciebie „transakcja wewnętrzna”

  • SET XACT_ABORT ON pomija błąd 266 spowodowany przez niezgodność @@TRANCOUNT
    A także zajmuje się takimi problemami jak ten "Limit czasu transakcji SQL Server" na dba.se

  • Pozwala to na TXN po stronie klienta (takie jak LINQ) Pojedyncza procedura składowana może być częścią transakcji rozproszonej lub XA lub po prostu zainicjowaną w kodzie klienta (powiedzmy .net TransactionScope)

Użycie:

  • Każdy przechowywany proces musi być zgodny z tym samym szablonem

Podsumowanie

  • Więc nie twórz więcej TXN niż potrzebujesz

Kod

CREATE PROCEDURE [Name]
AS
SET XACT_ABORT, NOCOUNT ON

DECLARE @starttrancount int

BEGIN TRY
    SELECT @starttrancount = @@TRANCOUNT

    IF @starttrancount = 0
        BEGIN TRANSACTION

       [...Perform work, call nested procedures...]

    IF @starttrancount = 0 
        COMMIT TRANSACTION
END TRY
BEGIN CATCH
    IF XACT_STATE() <> 0 AND @starttrancount = 0 
        ROLLBACK TRANSACTION;
    THROW;
    --before SQL Server 2012 use 
    --RAISERROR [rethrow caught error using @ErrorNumber, @ErrorMessage, etc]
END CATCH
GO

Uwagi:

  • Sprawdzanie wycofania jest w rzeczywistości zbędne, ponieważ SET XACT_ABORT ON . Jednak sprawia, że ​​czuję się lepiej, wygląda dziwnie bez i pozwala na sytuacje, w których nie chcesz tego włączać

  • Remus Rusanu ma podobną powłokę który wykorzystuje punkty zapisu. Wolę wywołanie atomowej bazy danych i nie używam częściowych aktualizacji, takich jak ich artykuł



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SET a SELECT podczas przypisywania zmiennych?

  2. uzyskaj nowy identyfikator rekordu SQL

  3. Jak mogę wstawić więcej niż 8000 znaków w kolumnie VARCHAR(MAX) za pomocą ExecuteNonQuery?

  4. Port 1433 zapory nie otwiera się

  5. Co robi 'COLLATE SQL_Latin1_General_CP1_CI_AS'?