Ce este un impas și cum să lupte

Kuzmenko Dmitry, epsilon Tehnologii



Să începem cu faptul că traducerea literală a impas înseamnă „blocare mort“. Atunci când se lucrează cu BDE (. Delphi, C ++ Builder), cu procedurile stocate nivel de client și IB Baza de date declanșatorii și, avem două cazuri mesajul impasul - citirea și actualizarea. Pentru blocul cu adevărat „mort“ nu este atins, deoarece IB SQL Link-ul începe orice tranzacție cu NO parametru WAIT (de ex. E. Nu se așteaptă să rezolve conflictul).







Interblocare atunci când modernizarea

Două tranzacții nu sunt finalizate încă, dar încercăm să actualizeze aceeași înregistrare sunt considerate competitive. Există două moduri de manipulare impas - așteptați și nu așteptați (cu așteptări și fără așteptări). BDE pentru orice mod de tranzacție IB este utilizat fără întârziere și cu modul de așteptare poate fi setată numai la lucrul direct cu IB API (de exemplu, prin FreeIBComponents).

„Ghinion“, desigur, aceasta este considerată o tranzacție, pentru a primi un mesaj de impas. Aceasta înseamnă că una dintre acțiunile întreprinse în tranzacție nu poate fi executată. Prin urmare, această tranzacție trebuie să fie anulate (derulare înapoi). Evitați tranzacțiile de lungă durată, care ar putea ajunge într-o situație - singura cale de ieșire din ea va încerca să înceapă din nou tranzacția și repetați toți pașii.

Reducerea numărului de potențiale conflicte de renovare poate reduce timpul de execuție a tranzacției. De exemplu, datele de la utilizator la început a acceptat, iar în cazul în care confirmă informațiile introduse, aplicația începe o tranzacție, rapid transmite date către server, și se termină. Pass-ul mai rapid tranzacția, cu atât mai probabil este finalizat cu succes. Acesta este motivul pentru care în 3.x BDE a introdus modul cached Actualizări (în cache modificări). Când Actualizări modificări în cache se acumulează pe partea de client a aplicației, atunci schimbarea ApplyUpdates metoda de apel „tras“ pe server. În orice caz, chiar dacă nu poate scăpa de tranzacție de reînnoire lung, va trebui să ia în considerare logica de aplicare și asigurați-vă că pentru a include în procesul de aplicare a conflictelor în curs de dezvoltare.

Impas în citire

Atenție! Tot ceea ce este descris mai jos probleme au fost fixate în BDE 4.01. Parametrul Indicativele de driver nu este necesară.







Impas apare atunci când citesc, practic, în SQL servere care folosesc pagina-blocare la citirea sau modificarea datelor (MS SQL și Sybase). Se pare ciudat că atunci când se lucrează cu IB, în care blocare existent (de blocare de actualizare conflict nu este considerat - nu se blochează, și anume conflictul), uneori apare încă impas atunci când citirea datelor.

Motivul este aceasta: Citire tranzacție la nivel de izolare Angajate în IB au două moduri - NU RECORD VERSION și RECORD VERSIUNEA (a se vedea descrierea parametrilor de tranzacție.). În primul caz, în cazul în care citirea nucleului de înregistrare IB detectează prezența neconfirmată versiunii (nealiniate) a acestei înregistrări, acesta returnează mesajul impas. Este ca și cum în cazul în care cererea indică faptul că în curând această înregistrare poate fi actualizat (de fapt, în modificările ReadCommitted greșite vor fi vizibile imediat după ce au fost confirmate (comite)). În modul VERSIUNEA RECORD, prezența versiunilor neaprobate de înregistrări sunt ignorate, și returnează întotdeauna versiunea veche a înregistrării.

S-ar părea, deci de ce nu funcționează în modul RECORD VERSIUNEA implicit BDE? Din păcate, a fost inițial stabilită - Citește tranzacție săvârsite în BDE se execută cu opțiunea NO RECORD VERSION - dar la versiunea Delphi 2.0 inconvenientelor aproape nimeni nu a observat. Dar de ce nu au observat, citiți mai departe.

Nivelul de izolare în AUTOCOMMIT în diferite versiuni ale BDE

În funcție de versiunea BDE a schimbat nivelul implicit de izolare. Când nu utilizați în mod explicit metodele de gestionare a tranzacțiilor (Database.StartTransaction, Commit și Rollback), atunci pentru ai face BDE. Nu mă crezi? Uită-te în Monitorul SQL. Cel mai important, tipul tranzacției implicit „cusute“, în SQL Link. Și chiar dacă ai pus pe forma unei componente TDatabase, și a schimbat proprietatea lui tiTransIsolation, aceasta nu afectează BDE, până când apelați metoda Database.StartTransaction.

Deci, ce sunt tranzacția începe BDE implicit.
  • Delphi 1.0, BDE 2.52 - Citire repetabilă
  • Delphi 2.0, BDE 3.x - Read Angajate
  • Delphi 3.0, BDE 4.0 - Read Committed
  • Delphi 3,01, BDE 4,01, 4,51 - Read Angajate cu RECORD VERSION parametru - impas și de citire lipsesc.

Astfel, impas și de lectură a observat doar în Delphi 2.0 aceasta se datorează faptului că tranzacția este implicit schimbat cu Angajate. Apropo, în READLINK.TXT pentru Delphi 2.x și 3.0 spune că dacă doriți să modificați tranzacția implicit pe Citire repetabilă, ar trebui să setați STEAGURI DRIVER setările driverului = 512 e. De fapt, „oferă compatibilitate“ comportamentul aplicației, transferat 2 al unui Delphi Delphi 1.

Atenție! Nu instalați PAVILIOANELE șofer, înainte de a citi READLINK.TXT.

Faptul că, de exemplu, în versiunea 4.0 numărul de steaguri a crescut:
  • 0 Citește Angajate, confirmarea imediată a oricăror modificări (poate provoca recitirea cursoare TQuery)
  • 512 Citire repetabilă, confirmarea imediată a oricăror modificări (poate provoca recitirea cursoare TQuery)
  • 4096 Citește comise, ca o confirmare a modificărilor efectuate COMMIT MENȚINEREA, păstrând contextul cursorului TQuery
  • 4608 repetabile citit, confirmare schimbarea este executat ca COMMIT MENȚINEREA, păstrând contextul cursorului TQuery