Oracle
 sql >> база данни >  >> RDS >> Oracle

Внедряване на оптимистично заключване в Oracle

Има два основни подхода за заключване.

Първо, имате песимистично заключване. При този подход заключвате реда (SELECT ... FOR UPDATE ), което не позволява на всеки друг да промени реда. След това правите UPDATE . Когато извършите промяната си, заключването се освобождава. В този случай няма нужда да имате колона номер на версия/време (поне да не поддържа заключване) и кодът е сравнително лесен.

Недостатъкът на песимистичното заключване е, че трябва да държите ключалката през цялото време, докато потребителят седи на страница, потенциално редактирайки данни. Това е технически наистина трудно, ако създавате уеб-базирано приложение, тъй като HTTP е протокол без състояние. Заявката, която първоначално изобразява страницата, обикновено ще получи връзка от пула за връзки, направете SELECT и след това върнете връзката към пула, след като страницата е готова. Следващата заявка за актуализиране на данните обикновено се случва при различна връзка с различна сесия на база данни, така че не можете да заключите реда в първата сесия и да го актуализирате във втората. Ако искате песимистично да заключите реда, ще трябва да свършите много работа в задния край, за да гарантирате, че една връзка с базата данни е свързана с определена сесия на средно ниво, докато потребителят не приключи с редактирането на данните. Това обикновено има много отрицателно въздействие върху мащабируемостта и въвежда всякакви проблеми с управлението на сесиите – откъде знаете, например, дали съм поискал страница, заключих ред и след това затворих браузъра си, без изобщо да изляза или да направя промяна? Колко дълго ще оставите записа заключен в базата данни? Какво се случва, ако друга сесия се опита да заключи реда? Колко време ще оставите този блок на сесията да чака заключване, ако първият човек излезе на обяд? Като цяло хората не прилагат песимистично заключване в уеб-базирани приложения, защото управлението на сесиите и състоянието на сесията е твърде непрактично.

Вторият вариант е оптимистично заключване. При този подход добавяте номер на версия/време към реда. Вие избирате този номер на версията/време, когато правите заявка за данните. След това използвате това във вашия WHERE клауза, когато по-късно извършите актуализацията и проверите колко реда действително са променени. Ако промените точно един ред, знаете, че редът не се е променил, откакто сте го прочели. Ако промените 0 реда, знаете, че редът се е променил и можете да се справите с грешката.

Така, например, ще изберете данните заедно с номера на версията

SELECT address_line1, city, state, zip, version
  FROM addressTable
 WHERE address_id = `<<some key>>`

Когато сте готови да направите актуализацията, бихте направили нещо подобно, когато използвате version във вашата UPDATE и извежда грешка, ако редът се промени

UPDATE addressTable
   SET address_line1 = `<<new address line 1>>`,
       city = `<<new city>>`,
       state = `<<new state>>`,
       zip = `<<new zip>>`,
       version = version + 1
 WHERE address_id = `<<some key>>`
   AND version = `<<version you read initially>>`

IF( SQL%ROWCOUNT = 0 )
THEN
  -- Darn.  The row must have changed since you read it.  Do something to
  -- alert the user.  Most likely, the application will need to re-query the
  -- data to see what the address has been changed to and then ask the user
  -- whether they want to re-apply the changes.
  RAISE_APPLICATION_ERROR( -20001, 'Oops, the row has changed since you read it.' );
END IF;

Тогава вашето приложение ще направи нещо полезно с грешката. Обикновено това би означавало да направите нещо като повторно запитване на данните, да представите промените на потребителя и да ги попитате дали все още искат да приложат промените си. Ако, например, прочета адрес и започна да го редактирам, отида на обяд, моят колега влезе, прочете същия адрес, направи някои редакции и го запазя, след което се върна и се опитам да запазя промените си, по принцип би имало смисъл да ми покаже нещо, което ми казва, че моят колега вече е променил адреса на нещо ново-- искам ли да продължа да правя редакции или искам да ги изоставя.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. проверете за валидна дата, която е декларирана в varchar2

  2. Ако изявление в рамките на клауза Къде

  3. Изберете от таблицата, като знаете само дата без час (ORACLE)

  4. Разказ за два фактора на групиране

  5. Изтрийте с ляво присъединяване в Oracle 10g