it-swarm-eu.dev

Časový limit transakcí serveru SQL

Existuje způsob, jak v SQL Server 2008 R2 způsobit časový limit pro úpravu databáze zahrnující transakci? Máme scénář, kdy náš kód aplikace zablokuje nebo vyvolá výjimku a neprovede vrácení nebo potvrzení. To pak způsobí, že ostatní relace přestanou čekat na dokončení transakce.

9

Rozšiřuje se Markova odpověď ...

Když dojde k události časového limitu klienta (například .net CommandTimeout), klient odešle "ABORT" na SQL Server. SQL Server pak jednoduše opustí zpracování dotazu. Žádná transakce není vrácena zpět, nejsou uvolněny žádné zámky.

Nyní je připojení vráceno do fondu připojení, takže není uzavřeno na serveru SQL. Pokud k tomu někdy dojde (prostřednictvím KILL nebo restartu klienta atd.), Transakce + zámky budou vymazány. Všimněte si, že sp_reset_connection je nevymaže nebo nevymaže, přestože je to inzerováno

Tento detrit z potratu bude blokovat další procesy.

Způsob, jak provést SQL Server jasné transakce + zámky na časový limit klienta (přísně události ABORT), je použít SET XACT_ABORT ON.

Můžete to ověřit otevřením 2 oken dotazů v SSMS:

Okno 1:

V nabídce Query..Query Options (Nastavení dotazu) nastavte časový limit na 5 sekund a poté spusťte

BEGIN TRAN
UPDATE sometable WITH (TABLOCKX) SET foo = foo WHERE 1 = 0;
WAITFOR DELAY '00:00:10' -- just has to be longer then timeout

Okno 2, bude to čekat navždy (nebo vyprší časový limit)

SELECT * FROM sometable

SET XACT_ABORT ON má také zajímavé vedlejší účinky:

  • @@ TRANCOUNT je nastaven na nulu v implicitním vrácení, ale chyba 266 je potlačena (k tomu dojde, pokud @@ TRANCOUNT je odlišný při vstupu a výstupu z uloženého proc)
  • XACT_STATE bude -1 (je to „odsouzeno k zániku“)

Tato kombinace znamená, že nemůžete použít SAVEPOINTS (i když si nemůžu vzpomenout na přesné chování) pro částečné odevzdání/vrácení peněz. Což mi vyhovuje

SO odkazy na SET XACT_ABORT:

Na vnořených uložených procích:

Na sp_reset_connection:

20
gbn

Odpovídám s váháním, protože ve vašem popisu problému není dostatek informací, abych si byl stoprocentně jistý, že je to nejlepší rada. „Visí nebo vyvolá výjimku“ naznačuje, že zdroj problému není správně pochopen, proto postupujte opatrně.

Nejjednodušší řešení je pravděpodobně SET XACT_ABORT ON.

XACT_ABORT určuje, zda SQL Server vrátí transakci v případě chyby spuštění. Výchozí SET XACT_ABORT OFF vrátí zpět pouze příkaz, který způsobil chybu, a ponechá všechny nadřazené transakce otevřené.

„Gotcha“ vedlejší účinek výchozího nastavení je, že časový limit může způsobit přesně stejný problém, otevřená transakce, za kterou se klienti musí starat a vrátit se zpět. Pokud se klient nezkouší/catch/rollback, transakce zůstane otevřená, dokud se nezúčastní (a cituji @gbn) ultra násilí KILL <spid>.

Články oft citované Erland Sommarskog články o zpracování chyb v SQL Server obsahují veškeré pozadí a strategii, kterou potřebujete pro řešení těchto scénářů a další.

Upravit (následující komentář): Pro identifikaci otevřených transakcí je sp_whoisactive pravděpodobně nejkompletnější funkcí.

11