Megosztás a következőn keresztül:


Az aktuális tranzakció elérése

A következőkre vonatkozik:SQL Server

Ha egy tranzakció aktív azon a ponton, amelyen az SQL Serveren futó közös nyelvi futtatókörnyezeti (CLR-) kód be van írva, a tranzakció a System.Transactions.Transaction osztályon keresztül lesz közzétéve. A Transaction.Current tulajdonság az aktuális tranzakció elérésére szolgál. A legtöbb esetben nem szükséges explicit módon hozzáférni a tranzakcióhoz. Adatbázis-kapcsolatok esetén ADO.NET automatikusan ellenőrzi Transaction.Current a Connection.Open metódus meghívásakor, és transzparens módon bevonja a kapcsolatot a tranzakcióba (kivéve, ha a Enlist kulcsszó értéke hamis a kapcsolati sztringben).

A Transaction objektumot érdemes közvetlenül az alábbi helyzetekben használni:

  • Ha olyan erőforrást szeretne felvenni, amely nem végez automatikus beléptetést, vagy valamilyen okból nem lett bevonva az inicializálás során.

  • Ha explicit módon szeretne erőforrást bevonni a tranzakcióba.

  • Ha meg szeretné szüntetni a külső tranzakciót a tárolt eljáráson vagy függvényen belül. Ebben az esetben TransactionScope. A következő kód például visszaállítja az aktuális tranzakciót:

    using(TransactionScope transactionScope = new TransactionScope(TransactionScopeOptions.Required)) { }
    

A cikk további része a külső tranzakciók megszakításának egyéb módjait ismerteti.

Külső tranzakció megszakítása

A külső tranzakciókat a következő módokon szakíthatja meg egy felügyelt eljárásból vagy függvényből:

  • A felügyelt eljárás vagy függvény egy kimeneti paraméter használatával visszaadhat egy értéket. A hívási Transact-SQL eljárás ellenőrizheti a visszaadott értéket, és szükség esetén végrehajthatja ROLLBACK TRANSACTION.

  • A felügyelt eljárás vagy függvény egyéni kivételt okozhat. A hívási Transact-SQL eljárás elkaphatja a felügyelt eljárás vagy függvény által a try/catch blokkban kidobott kivételt, és végrehajthatja a ROLLBACK TRANSACTION.

  • A felügyelt eljárás vagy függvény megszakíthatja az aktuális tranzakciót a Transaction.Rollback metódus meghívásával, ha egy adott feltétel teljesül.

Ha a Transaction.Rollback metódus egy felügyelt eljáráson vagy függvényen belül van meghívva, egy félreérthető hibaüzenettel kivételt küld, és egy próba-/fogási blokkba csomagolható. A hibaüzenet a következő kimenethez hasonló:

Msg 3994, Level 16, State 1, Procedure uspRollbackFromProc, Line 0
Transaction is not allowed to roll back inside a user defined routine, trigger or aggregate because the transaction is not started in that CLR level. Change application logic to enforce strict transaction nesting.

Ez a kivétel várható, és a kódvégrehajtás folytatásához a próba/fogás blokk szükséges. A try/catch blokk nélkül a kivétel azonnal megjelenik a hívási Transact-SQL eljárásban, és a felügyelt kód végrehajtása befejeződik. Amikor a felügyelt kód befejezi a végrehajtást, egy másik kivétel keletkezik:

Msg 3991, Level 16, State 1, Procedure uspRollbackFromProc, Line 1
The context transaction which was active before entering user defined routine, trigger or aggregate " uspRollbackFromProc " has been ended inside of it, which is not allowed. Change application logic to enforce strict transaction nesting. The statement has been terminated.

Ez a kivétel is várható, és a végrehajtás folytatásához a Transact-SQL utasítás körül meg kell jelennie egy próba/fogás blokknak, amely végrehajtja az eseményindítót aktiváló műveletet. A két kivétel ellenére a tranzakció vissza lesz állítva, és a módosítások nincsenek véglegesítése.

Példa

Az alábbi kód egy példa egy felügyelt eljárásból a Transaction.Rollback metódus használatával visszagördített tranzakcióra. Figyelje meg a felügyelt kód Transaction.Rollback metódusa körüli kipróbálási/fogási blokkot. A Transact-SQL szkript létrehoz egy szerelvényt és egy felügyelt tárolt eljárást. A EXEC uspRollbackFromProc utasítás egy próba-/fogási blokkba van csomagolva, így a felügyelt eljárás végrehajtásakor kidobott kivételt a rendszer elfogja.

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Transactions;

public partial class StoredProcedures
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void uspRollbackFromProc()
{
   using (SqlConnection connection = new SqlConnection(@"context connection=true"))
   {
      // Open the connection.
      connection.Open();

      bool successCondition = true;

      // Success condition is met.
      if (successCondition)
      {
         SqlContext.Pipe.Send("Success condition met in procedure.");
         // Perform other actions here.
      }

      //  Success condition is not met, the transaction will be rolled back.
      else
      {
         SqlContext.Pipe.Send("Success condition not met in managed procedure. Transaction rolling back...");
         try
         {
               // Get the current transaction and roll it back.
               Transaction trans = Transaction.Current;
               trans.Rollback();
         }
         catch (SqlException ex)
         {
            // Catch the expected exception.
            // This allows the connection to close correctly.
         }
      }

      // Close the connection.
      connection.Close();
   }
}
};

A szerelvény regisztrálása és végrehajtása a Transact-SQL

  1. Regisztrálja a szerelvényt.

    CREATE ASSEMBLY TestProcs
        FROM 'C:\Programming\TestProcs.dll';
    GO
    
    CREATE PROCEDURE uspRollbackFromProc
    AS EXTERNAL NAME TestProcs.StoredProcedures.uspRollbackFromProc;
    GO
    
  2. Futtassa az eljárást.

    BEGIN TRY
        BEGIN TRANSACTION;
    
        -- Perform other actions.
        EXECUTE uspRollbackFromProc;
    
        -- Perform other actions.
        PRINT N'Commiting transaction...';
    
        COMMIT TRANSACTION;
    END TRY
    BEGIN CATCH
        SELECT ERROR_NUMBER() AS ErrorNum,
               ERROR_MESSAGE() AS ErrorMessage;
        PRINT N'Exception thrown, rolling back transaction.';
        ROLLBACK;
        PRINT N'Transaction rolled back.';
    END CATCH
    GO
    
  3. A környezet megtisztítva.

    DROP PROCEDURE uspRollbackFromProc;
    GO
    
    DROP ASSEMBLY TestProcs;
    GO