Метод обработки, когда MySQL одновременно обновляет данные

MySQL

предисловие

При бэкенд-разработке мы неизбежно столкнемся с одновременным обновлением данных MySQL.Как бэкенд-разработчик, мы должны знать, как решать такие проблемы, и это также часть знаний, которую часто рассматривают на собеседованиях.

Будет ли ОБНОВЛЕНИЕ заблокировано?

Если оператор SQL выглядит следующим образом, будет ли он заблокирован?

UPDATE table1 SET num = num + 1 WHERE id=1;

ответ - нет

MySQL на самом деле поддерживает строки блокировки (InnoDB), и когда операции обновления / удаления, такие как «Добавить строки», это автоматически блокируется. ТолькоНет, пока не будет ключевого слова UPDATE с полной блокировкой., для приведенного выше оператора MySQL это не просто оператор UPDATE, он должен быть похож на два оператора SQL (псевдокод):

a = SELECT * FROM table1 WHERE id=1;
UPDATE table1 SET num = a.num + 1 WHERE id=1; 

Блокировки при выполнении оператора SELECT нет, только при выполнении UPDATE. Поэтому возникают несоответствия в обновленных данных во время параллельных операций. Причина найдена, и решение проблемы не за горами. Есть два решения этой проблемы:

  • Явно заблокировать SELECT через транзакцию
  • Используйте оптимистическую блокировку

ВЫБЕРИТЕ явную блокировку

Есть два способа заблокировать SELECT, а именно:

SELECT ... LOCK IN SHARE MODE       #共享锁,其它事务可读,不可更新
SELECT ... FOR UPDATE               #排它锁,其它事务不可读写
Если вы не используете эти два типа операторов, оператор SELECT не будет блокироваться по умолчанию. А для упомянутых выше сценариев необходимо использовать монопольную блокировку. Кроме того,Два приведенных выше утверждения могут вступить в силу только в транзакции, в противном случае они не вступят в силу.. Способ использования транзакций в командной строке MySQL следующий:

SET AUTOCOMMIT=0; 
BEGIN WORK; 
	a = SELECT num FROM table1 WHERE id=2 FOR UPDATE;  
	UPDATE table1 SET num = a.num + 1 WHERE id=2; 
COMMIT WORK;
Таким образом, пока данные обновляются в будущем, эта транзакция используется для работы, тогда в случае параллелизма транзакция, выполненная позже, будет заблокирована до завершения выполнения текущей транзакции. (Параллелизм изменен на последовательное выполнение через блокировки)

Используйте оптимистическую блокировку

Оптимистическая блокировка — это механизм реализации блокировки, который наивно предполагает, что все данные, которые необходимо изменить, не будут конфликтовать.Таким образом, он не блокирует данные перед обновлением, но просто запрашивать номер версии линий данных (здесь принадлежит номер версии пользовательских полей, необходимость в дополнительных полях в таблице на основе бизнеса, будет обновляться каждый раз увеличение или обновление).

Когда данные специально обновляются, информация о номере версии будет добавлена ​​к условиям обновления.

  • Если номер версии не изменился, это означает, что строка данных не обновлялась, а также соответствует условиям обновления, поэтому обновление пройдет успешно.
  • Когда номер версии изменяется, строка данных не может быть обновлена, поскольку условие не выполняется, и в это время необходимо выполнить операцию SQL. (повторно запросите строку данных и снова обновите данные с новым номером версии)

упражняться

Попрактикуйтесь в блокировке обновлений

Студенческая таблица с фрагментом данных


Откройте два клиента

Выполнить после первой открытой транзакции

select name from student where id = 1 for update;


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


В это время первая транзакция выполняет модификацию и фиксируется;


Было обнаружено, что выборочное выполнение второй транзакции заблокировано более чем на 4 секунды.


резюме

Как правило, эти два метода могут поддерживать параллельные операции обновления базы данных. Однако то, какой из них использовать, зависит от фактического сценария приложения, который лучше поддерживается сценарием приложения и оказывает наименьшее влияние на производительность.


Ссылка из: