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

PostgreSQL и ActiveRecord подизбират за състояние на състезание

Вашите опции са:

  • Изпълнение в SERIALIZABLE изолация. Взаимозависимите транзакции ще бъдат прекъснати при извършване на предаване, тъй като имат неуспешна сериализация. Ще получите много нежелана поща в регистъра на грешките и ще правите много повторения, но ще работи надеждно.

  • Дефинирайте UNIQUE ограничение и опитайте отново при неуспех, както отбелязахте. Същите проблеми като по-горе.

  • Ако има родителски обект, можете да SELECT ... FOR UPDATE родителския обект, преди да направите своя max заявка. В този случай трябва да SELECT 1 FROM bar WHERE bar_id = $1 FOR UPDATE . Вие използвате bar като заключване за всички foo s с този bar_id . След това можете да знаете, че е безопасно да продължите, стига всяка заявка, която извършва увеличаването на вашия брояч, прави това надеждно. Това може да работи доста добре.

    Това все още прави обобщена заявка за всяко повикване, което (за следваща опция) е ненужно, но поне не изпраща нежелана поща в регистрационния файл за грешки като горните опции.

  • Използвайте маса за брояч. Това бих направил. Или в bar , или в странична таблица като bar_foo_counter , придобийте идентификатор на ред с помощта на

    UPDATE bar_foo_counter SET counter = counter + 1
    WHERE bar_id = $1 RETURNING counter
    

    или по-малко ефективната опция, ако вашата рамка не може да се справи с RETURNING :

    SELECT counter FROM bar_foo_counter
    WHERE bar_id = $1 FOR UPDATE;
    
    UPDATE bar_foo_counter SET counter = $1;
    

    След това в същата транзакция , използвайте генерирания брояч за number . Когато се ангажирате, редът на таблицата с брояч за този bar_id се отключва за следваща заявка за използване. Ако се върнете назад, промяната се отхвърля.

Препоръчвам подхода на брояча, използвайки специална странична таблица за брояча, вместо добавяне на колона към bar . Това е по-чисто за моделиране и означава, че създавате по-малко раздуване на актуализацията в bar , което може да забави заявките към bar .




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Заключете за SELECT, така че друг процес да не получи стари данни

  2. Как да получите ключовите полета за таблица във функцията plpgsql?

  3. C#, Entity Framework Core &PostgreSql:вмъкването на един ред отнема 20+ секунди

  4. Кой е най-добрият начин за моделиране на връзка много към много

  5. Използване на ruby ​​за преобразуване на цели числа без знак, съхранени като знак, обратно в оригиналната стойност