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

Изолация на транзакции в PostgreSQL

PostgreSQL се предлага със солидни, изпитани във времето функции, които ви позволяват да дефинирате какво точно трябва да се случи, когато множество клиенти се опитат да актуализират едни и същи данни едновременно. Едно от тях е нивото на изолация на транзакциите.

Прочетете, за да научите повече за това как работи изолацията на транзакциите в PostgreSQL.

Транзакции и ниво на изолация

Транзакциите са основният начин за мутиране на данни в RDBMS. Съвременните RDBMS позволяват на повече от една транзакция да се изпълняват едновременно и следователно идват с различни инструменти – някои стандартни, някои специфични за RDBMS – за разработчиците на приложения, за да определят как техните транзакции трябва или не трябва да взаимодействат с други транзакции.

Нивата на изолация на транзакциите и песимистичните заключвания са два такива инструмента. Въпреки че те са необходими за целостта и производителността на данните, за съжаление не са интуитивни за разбиране или използване.

Нивото на изолация на транзакция в PostgreSQL може да бъде едно от следните:

  • Прочетете ангажирано
  • Повтарящо се четене
  • Може да се сериализира

Всяка транзакция има ниво на изолация, зададено на едно от тези, когато е създадена. Нивото по подразбиране е „прочетено е извършено“.

Имайте предвид, че стандартът на SQL също дефинира „четене без ангажимент“, което не се поддържа в Postgres. Трябва да използвате най-близкото, по-високо ниво на „прочетено ангажирано“.

Нека видим какво означават тези нива.

Прочетете е ангажирано

Какво се случва, когато една (незавършена) транзакция вмъкне редове в таблица, а другата (също незавършена) транзакция се опита да прочете всички редове в таблицата? Ако тази втора транзакция може да види редовете, вмъкнати от първата, тогава това read се нарича мръсно четене – защото първата транзакция може да се върне назад, а тази втора транзакция би прочела „фантомни“ редове, които никога не са съществували.

Прочетеното е извършено ниво на изолация гарантира, че мръсни четения никога няма да се случат. Ето един пример:

Както можете да видите, втората транзакция не можа да прочете данни от първата транзакция, които са все още незаети. В PostgreSQL не е възможно да се понижи нивото на изолация до под това ниво, така че да са разрешени мръсни четения.

Повтарящо се четене

Друг проблем е този с неповторяемите четения. Това се случва, когато транзакция чете ред и след това го чете отново малко по-късно, но получава различен резултат - защото редът е актуализиран между тях от друга транзакция. Четенето стананеповторяемо , както е показано в този пример:

За да разрешите този проблем, задайте нивото на изолация на транзакцията на „repeatableread“. След това PostgreSQL ще гарантира, че второто (или което и да е) четене също ще върне същия резултат като първото четене. Ето същия сценарий на надстроеното ниво на изолация:

Имайте предвид, че нивото на изолация е посочено заедно с оператора BEGIN. Възможно е също да се посочи това на ниво връзка (като параметър на връзката), като конфигурационен параметър (default_transaction_isolation ) и използвайки оператора SET TRANSACTION.

Може да се сериализира

Следващото ниво на изолация адресира проблема с загубените актуализации . Актуализациите, извършени в една транзакция, могат да бъдат „загубени“ или презаписани от друга транзакция, която се изпълнява едновременно, както е показано тук:

Тук UPDATE на втората транзакция блокира, тъй като PostgreSQL поставя блокиране, за да предотврати друга актуализация, докато първата транзакция не приключи. Въпреки това, промяната на първата транзакция се губи, защото втората „презаписа“ реда.

Ако този вид поведение не е приемливо, можете да надстроите нивото на изолация до сериализиращо се:

На това ниво записването на втората транзакция е неуспешно. Действията на втората транзакция се основават на факти, които са били обявени за невалидни към момента, в който е била на път да бъде извършена.

Въпреки че сериализацията осигурява най-високо ниво на безопасност, това също означава, че приложението трябва да открие такива неуспехи на записване и да опита отново цялата транзакция.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Django + Postgres + Големи времеви серии

  2. Как да използвам повторно резултат за клаузите SELECT, WHERE и ORDER BY?

  3. как да проверите вида на стойността в postgres

  4. Как да определя последния ден от предишния месец с помощта на PostgreSQL?

  5. Намаляване на параметъра postgresql.conf наведнъж