параллельное выполнение транзакций mysql innodb - PullRequest
4 голосов
/ 02 августа 2011

У меня есть 3 таблицы

Продукты

product_id
max_products_can_sell
max_products_can_sell_to_individual

покупок

user_id
product_id
product_id *1012* product_id *1011* product_id *1011* product_id *1012*количество

резервирование

product_id
user_id
количество

Надеюсь, вы поняли структуру.

Теперь, когда когда-либо пользователь пытается купитьпродукт, я должен проверить оставшиеся позиции по max_products_can_sell - (проданное количество + зарезервированное количество).

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

Теперь актуальный вопрос: как решать проблемы параллелизма здесь.Например: ручка продукта имеет только 1.два пользователя запрашивают Reserve.php.

"a" запрос пользователя Reserve.php и доступное перо 1.но перед вставкой, для "b" пользователю доступно перо 1.поэтому два пользователя оставляют за собой ручку.

Я использую таблицу innodb.Как с этим справиться?

EIDT

  $query = SELECT count(*) as sold     FROM purchases WHERE product_id = 1;    
    $query = SELECT count(*) as reserved FROM reservations WHERE product_id = 1;     
    $items_remaining = $sold+$reserved;       

    if ($items_remaining) {      
       //INSERT data to reservations    
    } 

Теперь мне нужно убедиться, что никакие другие запросы не будут мешать и выполнять тот же SELECT (читая «старое значение»).'до того, как это соединение завершит обновление строки.

Как сказал Dan , я могу заблокировать таблицу TABLES, чтобы убедиться, что только одно соединение делает это одновременно, и разблокировать ее, когда ясделано, но это кажется излишним. Будет ли перенос в транзакцию делать то же самое (гарантируя, что никакое другое соединение не попытается выполнить тот же процесс, пока другое все еще обрабатывает)? Или будет SELECT ... FOR UPDATE или SELECT ...LOCK IN SHARE MODE будет лучше?

Я не понимаю, использовать ли транзакции или таблицы блокировки или использовать обе. Пожалуйста, предложите мне ..

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

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

Подскажите, пожалуйста, как мне с этим справиться?

Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 03 августа 2011

Я бы заблокировал только запись о продукте (с выберите для обновления - обратите внимание, выберите блокировку в режиме общего доступа, чтобы другой пользователь не мог купить тот же продукт), а затем выполните оставшуюся операцию.Таким образом, я не буду блокировать покупку других продуктов (в то время как блокировка таблицы заблокирует любые операции записи, независимо от того, есть ли для продукта 1 или продукта 2) И почему вы сохраняете свойство max_product_can_sell вместо (или не вместе с) available_quantityсвойство?

Как сказал Дэн, я могу заблокировать таблицу TABLES, чтобы удостовериться, что только одно соединение делает это за раз, и разблокировать ее, когда я закончу, но это кажется излишним.Будет ли перенос в транзакцию делать то же самое (гарантируя, что никакое другое соединение не попытается выполнить тот же процесс, пока другое все еще обрабатывает)?

Зависит от уровня изоляции.В сериализуемом - да, на более низких уровнях, я почти уверен, нет.

1 голос
/ 02 августа 2011

Блокировка таблицы, выполнение транзакции, разблокировка таблицы. Любые запросы, поступающие при открытой транзакции, будут задерживаться в ожидании снятия блокировки.

http://dev.mysql.com/doc/refman/5.1/en/lock-tables.html

...