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

Как се заключват innodb таблиците, когато тригерът ON INSERT се обработва?

Що се отнася до проблемите с едновременността, имате „лесно“ начин за предотвратяване на проблеми с паралелността във втория метод, вътре във вашата транзакция извършете избор на реда за статии (For update сега е имплицитна). Всяко едновременно вмъкване в същия артикул няма да може да получи същото заключване и ще ви чака.

С новите нива на изолация по подразбиране, без дори да използвате ниво на сериализация в транзакцията, няма да видите нито едно едновременно вмъкване в таблицата за гласуване до края на вашата транзакция. Така че вашата SUM трябва да остане последователна или да изглежда последователна . Но ако едновременна транзакция вмъкне гласуване за същата статия и ангажимент преди вас (и тази 2-ра не вижда вашето вмъкване), последната транзакция за ангажиране ще презапише брояча и ще загубите 1 глас. Така че направете заключване на ред на статия, като използвате избор преди (и вършете работата си в транзакция, разбира се). Лесно е за тестване, отворете 2 интерактивни сесии на MySQL и стартирайте транзакции с BEGIN.

Ако използвате тригера, вие сте в транзакция по подразбиране. Но мисля, че трябва да извършите също и избора в таблицата със статии, за да направите имплицитно заключване на ред за едновременно изпълнявани задействания (по-трудно за тестване).

  • Не забравяйте тригерите за изтриване.
  • Не забравяйте задействанията за актуализиране.
  • Ако не използвате задействания и код за оставане, внимавайте, че всяка заявка за вмъкване/изтриване/актуализиране на vote трябва да извърши заключване на реда на съответната статия преди в транзакцията. Не е много трудно да забравите един.

Последна точка:извършвайте по-трудни транзакции, преди да започнете транзакцията, използвайте:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

По този начин нямате нужда от заключване на редове на статии, MySQL ще открие, че се появява потенциално записване на същия ред и ще блокира другите транзакции, докато не завършите. Но не използвайте нещо, което сте изчислили от предишна заявка . Заявката за актуализиране ще чака освобождаване на заключване на статии, когато заключването бъде освободено от първата транзакция COMMIT изчисляването на SUM трябва да се направи отново, за да се преброят. Така че заявката за актуализиране трябва да съдържа SUM или направете допълнение.

update articles set nb_votes=(SELECT count(*) from vote) where id=2; 

И тук ще видите, че MySQL е интелигентен, открива се блокиране, ако 2 транзакции се опитват да направят това, докато вмъкването е извършено едновременно. В нивата на сериализация не намерих начин да получа грешна стойност с :

   SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
   BEGIN;
       insert into vote (...
       update articles set nb_votes=(
         SELECT count(*) from vote where article_id=xx
       ) where id=XX;
    COMMIT;

Но бъдете готови да се справите с нарушаването на транзакцията, която трябва да повторите.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySqlConnectionStringBuilder - Свържете се със сертификати

  2. Вмъкване на множество текстови файлове, разделени с табулатори, в MySQL с Python?

  3. Не може да се зареди com.mysql.jdbc.Driver

  4. Справка:Какво е перфектен примерен код, използващ разширението MySQL?

  5. Изберете всички дублиращи се редове въз основа на една или две колони?