Nejjednodušším řešením deadlocku je spustit znova transakci, která se stala jeho obětí. Transakce, která se stala obětí deadlocku je neplatná. Nedá se nad ní udělat commit, ani rollback po savepoint. Jedinnou možností je rollback celé transakce. Z toho plyne, že retry logiku můžu nasadit jen v místě, kde mám kontrolu nad zahájením transakce. Celou transakci pak zabalím do cyklu WHILE a v něm se ji v případě deadlocku pokusím několikrát zopakovat. Pokud se mi to nepodaří ani na několikátý pokus, pak chybu vypropaguju ven.
DECLARE @pocetPokusu INT = 1; WHILE (1=1) BEGIN BEGIN TRY BEGIN TRAN RAISERROR('pokousim se vykonat transakci',1,1) WITH NOWAIT; EXECUTE(' CREATE TYPE dbo.instantiDeadlock AS TABLE( Id INT NOT NULL ) ') EXEC(' declare @t dbo.instantiDeadlock;') COMMIT; BREAK; END TRY BEGIN CATCH ROLLBACK; IF ERROR_NUMBER() = 1205 AND @pocetPokusu < = 3--jsem obeti deadlocku a jeste jsem si nedal 3 pokusy BEGIN RAISERROR('jsem obeti deadlocku',1,1) WITH NOWAIT; SET @pocetPokusu += 1; END ELSE THROW; END CATCH END IF EXISTS (SELECT 1 FROM sys.table_types tt WHERE tt.name = 'instantiDeadlock') DROP TYPE instantiDeadlock
pokousim se vykonat transakci Msg 50000, Level 1, State 1 jsem obeti deadlocku Msg 50000, Level 1, State 1 pokousim se vykonat transakci Msg 50000, Level 1, State 1 jsem obeti deadlocku Msg 50000, Level 1, State 1 pokousim se vykonat transakci Msg 50000, Level 1, State 1 jsem obeti deadlocku Msg 50000, Level 1, State 1 pokousim se vykonat transakci Msg 50000, Level 1, State 1 Msg 1205, Level 13, State 55, Line 6 Transaction (Process ID 80) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.