XACT_ABORT OFF vs COMMIT în declanșator (Administrarea bazelor de date, Server Sql, Declanșează, Sql Server 2014)

Mansfield a intrebat.

Am un declanșator pe un tabel care declanșează alte câteva procese. Cu toate acestea, aș dori să mă asigur că, chiar dacă celelalte procese eșuează, inserția este confirmată cu succes în tabelul original.

Am făcut acest lucru prin emiterea unei comenzi explicite COMMIT TRAN în declanșator înainte de a apela cealaltă procedură. Acest lucru pare să fi funcționat bine, cu excepția unui mesaj de eroare inestetic:

Msg 3609, Level 16, State 1, Line 3 Tranzacția s-a încheiat în declanșator. Lotul a fost întrerupt.

După ce am făcut mai multe cercetări, am modificat procedura, adăugând SET XACT_ABORT OFF; în partea de sus și am eliminat confirmarea explicită. Acest lucru pare să fi avut același efect.

Care dintre acestea este de preferat? Există vreo capcană de care ar trebui să fiu conștient cu oricare dintre aceste metode?

Comentarii

  • Uitați-vă la brokerul de servicii pentru a lansa aceste alte procese într-o altă tranzacție. –  > Por Martin Smith.
  • @MartinSmith Folosesc deja brokerul de servicii. –  > Por Mansfield.
1 răspunsuri
Solomon Rutzky

Dacă nu aveți niciun alt cod în declanșator care ar trebui să aibă voie să anuleze INSERT-ul, încercați următoarele:

  • Păstrați XACT_ABORT OFF
  • Puneți COMMIT TRAN înapoi
  • Adăugați un BEGIN TRAN la sfârșitul declanșatorului

Aceasta ar trebui să fie aceeași problemă ca și în cazul în care aveți o tranzacție deschisă, executați un proc, iar în acel proc faceți un ROLLBACK (sau chiar doar un BEGIN TRAN și nu COMMIT sau ROLLBACK): va da eroare spunând valoarea de @@TRANCOUNT este diferită între intrarea și ieșirea din proc.

Comentarii

  • Ei bine, eu nu primesc niciun mesaj de eroare. Care este rostul lui XACT_ABORT în această situație, dacă fac deja un commit? –  > Por Mansfield.
  • @Mansfield Pentru că XACT_ABORT controlează dacă orice eroare nu eșuează în lot. Ați spus deja că nu doriți acest lucru. Poate că este în regulă să o lăsați ca ON, dar ar trebui să testați punând un SELECT 1/0; în declanșator pentru a vedea efectul. –  > Por Solomon Rutzky.
  • Bine, deci, doar ca să înțeleg: COMMIT TRAN se asigură că datele sunt confirmate (evident), BEGIN TRAN previne apariția unei erori, și XACT_ABORT face ca lotul să reușească în ciuda oricăror erori? –  > Por Mansfield.
  • @Mansfield Ei bine, făcând acest test simplu va fi mai bun decât memoria mea, dar tot cred că aveți nevoie, sau ar trebui să aveți, un TRY / CATCH în declanșator, astfel încât să puteți gestiona erorile în mod corespunzător. –  > Por Solomon Rutzky.
  • Am făcut testul și a funcționat – vreau doar să mă asigur că am înțeles ce fac. Aveam deja try/catch-ul acolo. Vă mulțumim pentru ajutor! –  > Por Mansfield.