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

Грешка в механизма за заключване на PostgreSQL или неразбиране на механизма

Няма грешка и не мисля, че разбирате нещо погрешно; пропускате само няколко части от пъзела.

Външните ключове се изпълняват вътрешно чрез заключване на ниво ред; започвайки от Postgres 8.1 и до 9.2, когато актуализирате референтната таблица (apples в този случай), се задейства заявка, която прави SELECT FOR SHARE върху таблицата с препратки (trees ). Така че SELECT FOR UPDATE в първата транзакция блокира SELECT FOR SHARE на референтната цялост за втората транзакция. Това е причината за блокирането във втората команда.

Сега те чувам да крещиш:„Чакай! Защо блокира на втората команда, а не на първата? Обяснението е просто, наистина - това е само защото има проста оптимизация, която пропуска вътрешния SELECT FOR SHARE когато ключът не се променя. Това обаче е опростено, тъй като ако актуализирате кортеж втори път, тази оптимизация няма да се задейства, защото е по-трудно да се проследят оригиналните стойности. Оттук и блокирането.

Може също да се чудите защо казах, че това е до 9.2 --- какво става с 9.3? Основната разлика е, че в 9.3 той използва SELECT FOR KEY SHARE , което е ново, по-леко ниво на заключване; позволява по-добра едновременност. Ако опитате вашия пример в 9.3 и също промените SELECT FOR UPDATE до SELECT FOR NO KEY UPDATE (който е по-лек режим от SELECT FOR UPDATE което казва, че може би ще актуализирате кортежа, но обещавате да не променяте първичния ключ и обещавате да не го изтривате), трябва да видите, че не блокира. (Също така можете да опитате АКТУАЛИЗАЦИЯ на посочения ред и ако не промените първичния ключ, той също няма да блокира.)

Тези неща за 9.3 бяха въведени чрез кръпка от вас наистина като http://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=0ac5ad5134f2769ccbaefec73844f8504c4d6182 и мисля, че беше доста готин хак (Съобщението за ангажиране има още подробности, ако ви интересуват такива неща). Но внимавайте, не използвайте версии преди 9.3.4, тъй като тази корекция беше толкова изключително сложна, че няколко сериозни грешки останаха незабелязани и ние поправихме едва наскоро.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Съпоставяне на сериен тип PostgreSQL с анотации за хибернация

  2. Как да КОПИРАМ ИМПОРТ json файл в postgres?

  3. Генерирайте произволно число в диапазона 1 - 10

  4. Rails:Как да създадете колона за време с часова зона на postgres

  5. Промяна на типа на полето varchar на цяло число:не може да се прехвърля автоматично към тип цяло число