Kuzmenko Dmitry
Epsylon Technologies
În primul rând, traducerea literală a cuvântului "impas" înseamnă "impas". 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 începe fiecare tranzacție cu opțiunea NO WAIT (de exemplu, nu se așteaptă o soluționare a conflictului).
Blocaj la modernizare
Două tranzacții care nu sunt încă finalizate, dar încercați să actualizați aceleași înregistrări sunt considerate concurente. Există două moduri de prelucrare a blocajului - așteptați și nu așteptați (cu și fără așteptare). În BDE, pentru orice tranzacție IB, modul este utilizat fără așteptare și modul așteptare poate fi setat numai atunci când lucrați direct cu API-ul IB (de exemplu, prin FreeIBComponents).
"Nefericită", desigur, este o tranzacție care a primit un mesaj despre impas. Aceasta înseamnă că una dintre acțiunile efectuate în cadrul tranzacției nu poate fi efectuată. Prin urmare, o astfel de tranzacție trebuie anulată (returnare). Trebuie să evitați tranzacțiile lungi care pot intra în această situație - singura cale de ieșire din aceasta va fi să încercați să începeți din nou tranzacția și să repetați toate acțiunile.
Pentru a reduce numărul de posibile conflicte de actualizare, puteți reduce timpul tranzacției. De exemplu, mai întâi datele sunt primite de la utilizator și dacă confirmă informațiile introduse, aplicația inițiază tranzacția, transferă rapid datele pe server și se termină. Cu cât tranzacția este mai rapidă, cu atât mai multe șanse vor fi realizate cu succes. De aceea BDE 3.x a introdus modul Cached Updates. Cu actualizările cache, modificările sunt acumulate pe partea client a aplicației, iar atunci când se numește metoda ApplyUpdates, modificările sunt "trase" către server. În orice caz, chiar dacă nu puteți scăpa de tranzacțiile de actualizare de lungă durată, trebuie să vă gândiți la logica aplicației și asigurați-vă că ați inclus în cerere soluționarea conflictelor emergente.
Blocare în timp ce citiți
Toate problemele descrise mai jos sunt fixate în BDE 4.01. Nu este necesar să specificați parametrul DRIVER FLAGS.
Blocarea la citire apare în principal în serverele SQL care utilizează blocarea paginilor atunci când citesc sau modifică date (MS SQL și Sybase). Se pare ciudat că atunci când lucrăm cu IB, în care nu există niciun blocaj (conflictul de blocare nu este considerat un conflict - nu este un blocaj, ci un conflict), uneori se produce un blocaj atunci când se citesc date.
Motivul este următorul: operațiunile de nivel de izolare Citiți comitetele au în IB două moduri - NU VERSIUNEA RECORDULUI și VERSIUNEA ÎNREGISTRĂ. În primul caz, dacă motorul IB detectează o versiune neacordată a acestei înregistrări la citirea înregistrării, acesta returnează un mesaj de blocare. Este oarecum o semnalizare a aplicației că în curând această înregistrare va fi probabil actualizată (deoarece în ReadComded schimbările altor persoane vor fi vizibile imediat după confirmarea lor (comiterea)). În modul RECORD VERSION, versiunile neconfirmate ale înregistrărilor sunt ignorate, iar vechea versiune a înregistrării este întotdeauna returnată.
Se pare că, de ce nu ar funcționa BDE în mod implicit în modul RECORD VERSION. Din nefericire, a fost inițial stabilit - tranzacția Read Committed în BDE este începută cu parametrul NO RECORD VERSION - dar înainte de Delphi 2.0, aproape nimeni nu a observat acest neplăcut. Și de aceea nu au observat, citim mai departe.
Nivel de izolare în AUTOCOMMIT în diferite versiuni ale BDE
În funcție de versiunea BDE, nivelurile implicite de izolare au fost modificate. Când nu utilizați în mod explicit metode de gestionare a tranzacțiilor (Database.StartTransaction, Commit și Rollback), BDE o face pentru dvs. Nu mă crede. Uită-te în SQL Monitor. Cel mai important lucru este că tipul de tranzacție este "cusut" implicit î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 fel de tranzacții începe prin BDE implicit.
- Delphi 1.0, BDE 2.52 - Citește repetabil
- Delphi 2.0, BDE 3.x - Citiți comitetul
- Delphi 3.0, BDE 4.0 - Read Committed
- Delphi 3.01, BDE 4.01, 4.51 - Read Committed cu parametrul RECORD VERSION - blocaj - și nu există citiri.
Astfel, impas și de lectură a observat doar în Delphi 2.0, aceasta se datorează faptului că tranzacția implicit este 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 parametrii PAVILIOANELE driver Driver = 512. Aceasta este, de fapt, "asigură compatibilitatea" comportamentului aplicațiilor transferate către Delphi 2 de la Delphi 1.
Nu instalați FLAG-urile DRIVER fără a citi în prealabil READLINK.TXT. Problema este că, de exemplu, în versiunea 4.0 numărul de steaguri a crescut:
- 0 Citiți Comunicat, confirmarea imediată a oricăror modificări (poate determina re-citirea cursorilor TQuery)
- 512 Citire repetată, confirmare imediată a oricăror modificări (poate determina re-citirea cursorilor TQuery)
- 4096 Citiți angajamentul, confirmarea modificărilor este efectuată ca COMMIT RETAIN, salvând contextul cursorilor TQuery
- 4608 Citire repetabilă, confirmarea modificărilor este efectuată ca COMMIT RETAIN, salvând contextul cursorilor TQuery