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

Кога да използвате SELECT ... ЗА АКТУАЛИЗИРАНЕ?

Единственият преносим начин да постигнете съгласуваност между стаите и таговете и да гарантирате, че стаите никога не се връщат, след като са били изтрити, е да ги заключите с SELECT FOR UPDATE .

Въпреки това в някои системи заключването е страничен ефект от контрола на паралелността и постигате същите резултати, без да указвате FOR UPDATE изрично.

За да разреши този проблем, Thread 1 трябва да SELECT id FROM rooms FOR UPDATE , като по този начин предотвратява изтриването на Thread 2 от rooms докато завърши Тема 1. Вярно ли е?

Това зависи от контрола за едновременност, който използва вашата система за бази данни.

  • MyISAM в MySQL (и няколко други стари системи) заключва цялата таблица за продължителността на заявката.

  • В SQL Server , SELECT заявките поставят споделени заключване на записите / страниците / таблиците, които са проверили, докато DML заявките поставят заключвания за актуализиране (които по-късно се повишават до изключителни или се понижават до споделени ключалки). Изключителните ключалки са несъвместими със споделените ключалки, така че или SELECT или DELETE заявката ще се заключи, докато друга сесия не бъде ангажирана.

  • В бази данни, които използват MVCC (като Oracle , PostgreSQL , MySQL с InnoDB ), DML query създава копие на записа (по един или друг начин) и като цяло читателите не блокират писателите и обратно. За тези бази данни, SELECT FOR UPDATE би било полезно:ще заключи или SELECT или DELETE заявка, докато друга сесия не се ангажира, точно както SQL Server прави.

Кога трябва да се използва REPEATABLE_READ изолация на транзакциите срещу READ_COMMITTED с SELECT ... FOR UPDATE ?

Като цяло, REPEATABLE READ не забранява фантомни редове (редове, които са се появили или изчезнали в друга транзакция, вместо да бъдат променени)

  • В Oracle и по-стари PostgreSQL версии, REPEATABLE READ всъщност е синоним на SERIALIZABLE . По принцип това означава, че транзакцията не вижда промени, направени след като е започнала. Така че в тази настройка последната Thread 1 query ще върне стаята, сякаш никога не е била изтрита (което може или не може да е това, което сте искали). Ако не искате да показвате стаите, след като са били изтрити, трябва да заключите редовете с SELECT FOR UPDATE

  • В InnoDB , REPEATABLE READ и SERIALIZABLE са различни неща:четци в SERIALIZABLE режимът задава заключвания на следващия ключ на записите, които оценяват, ефективно предотвратявайки едновременния DML на тях. Така че нямате нужда от SELECT FOR UPDATE в сериализиращ се режим, но се нуждаят от тях в REPEATABLE READ или READ COMMITED .

Имайте предвид, че стандартът за режимите на изолация предписва да не виждате определени странности във вашите заявки, но не дефинира как (със заключване или с MVCC или по друг начин).

Когато кажа „не се нуждаете от SELECT FOR UPDATE " Наистина трябваше да добавя "поради страничните ефекти от внедряването на определена база данни".



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQLSTATE[HY000] [1045] Достъпът е отказан за потребител 'username'@'localhost' с помощта на CakePHP

  2. Разбиране на изгледите в SQL

  3. LINQ за Java инструмент

  4. Как да проверите размера на база данни в MySQL

  5. MySQL - SELECT WHERE поле В (подзаявка) - Изключително бавно защо?