Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Aplica-se a:SQL Server
Se uma transação estiver ativa no ponto em que o código CLR (Common Language Runtime) em execução no SQL Server for inserido, a transação será exposta por meio da classe System.Transactions.Transaction. A propriedade Transaction.Current é usada para acessar a transação atual. Na maioria dos casos, não é necessário acessar a transação explicitamente. Para conexões de banco de dados, o ADO.NET verifica Transaction.Current automaticamente quando o método Connection.Open é chamado e inscreve de forma transparente a conexão nessa transação (a menos que a palavra-chave Enlist esteja definida como false na cadeia de conexão).
Talvez você queira usar o objeto Transaction diretamente nos seguintes cenários:
Se você quiser inscrever um recurso que não faça alistamento automático ou que, por algum motivo, não tenha sido alistado durante a inicialização.
Se você quiser inscrever explicitamente um recurso na transação.
Se você quiser encerrar a transação externa de dentro do seu procedimento armazenado ou função. Nesse caso, você usa TransactionScope. Por exemplo, o código a seguir reverte a transação atual:
using(TransactionScope transactionScope = new TransactionScope(TransactionScopeOptions.Required)) { }
O restante deste artigo descreve outras maneiras de cancelar uma transação externa.
Cancelar uma transação externa
Você pode cancelar transações externas de um procedimento ou função gerenciada das seguintes maneiras:
O procedimento ou função gerenciada pode retornar um valor usando um parâmetro de saída. O procedimento de Transact-SQL de chamada pode verificar o valor retornado e, se apropriado, executar
ROLLBACK TRANSACTION.O procedimento ou função gerenciada pode gerar uma exceção personalizada. O procedimento de chamada Transact-SQL pode capturar a exceção lançada pelo procedimento gerenciado ou função em um bloco try/catch e executá
ROLLBACK TRANSACTION.O procedimento gerenciado ou função pode cancelar a transação atual chamando o método
Transaction.Rollbackse uma determinada condição for atendida.
Quando o método Transaction.Rollback é chamado dentro de um procedimento gerenciado ou função, ele lança uma exceção com uma mensagem de erro ambígua e pode ser encapsulado em um bloco try/catch. A mensagem de erro é semelhante à seguinte saída:
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.
Essa exceção é esperada e o bloco try/catch é necessário para que a execução do código continue. Sem o bloco try/catch, a exceção é imediatamente lançada para o procedimento de chamada Transact-SQL e a execução do código gerenciado é concluída. Quando o código gerenciado termina a execução, outra exceção é gerada:
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.
Essa exceção também é esperada e, para que a execução continue, você deve ter um bloco try/catch ao redor da instrução Transact-SQL que executa a ação que dispara o gatilho. Apesar das duas exceções lançadas, a transação é revertida e as alterações não são confirmadas.
Exemplo
O código a seguir é um exemplo de uma transação que está sendo revertida de um procedimento gerenciado usando o método Transaction.Rollback. Observe o bloco try/catch ao redor do método Transaction.Rollback no código gerenciado. O script Transact-SQL cria um assembly e um procedimento armazenado gerenciado. A instrução EXEC uspRollbackFromProc é encapsulada em um bloco try/catch, para que a exceção lançada quando o procedimento gerenciado concluir a execução seja capturada.
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();
}
}
};
Registrar e executar o assembly em Transact-SQL
Registre a montagem.
CREATE ASSEMBLY TestProcs FROM 'C:\Programming\TestProcs.dll'; GO CREATE PROCEDURE uspRollbackFromProc AS EXTERNAL NAME TestProcs.StoredProcedures.uspRollbackFromProc; GOExecute o procedimento.
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 GOLimpe o seu ambiente.
DROP PROCEDURE uspRollbackFromProc; GO DROP ASSEMBLY TestProcs; GO