параллелизм в innodb - PullRequest
       16

параллелизм в innodb

3 голосов
/ 23 июня 2011

у меня есть такой код

reserve.php

$r=mysql_query("select count(*) from ticket");
$rec=mysql_fetch_array($r);
if ($rec[0]==0)
{
insert into ticket values .....
}

У меня только 1 билет. два пользователя запрашивают Reserve.php.

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

таблица - это Innodb. как это предотвратить? транзакция, блокировка таблицы или что?

Ответы [ 2 ]

3 голосов
/ 23 июня 2011

В этих ситуациях я обычно просто использую инструкцию UPDATE и проверяю, сколько записей было затронуто (mysql_affered_rows) обновлением.

 UPDATE tickets SET ticket_count=ticket_count-1 WHERE ticket_id=123 AND ticket_count>0

Если кто-то сначала уменьшил счетчик, обновление не произойдет, и вы не дадите пользователю билет. Автокоммит должен быть включен, чтобы обновление было отдельной «транзакцией».

Кроме того, вы можете изменить свой SELECT на SELECT ... ДЛЯ ОБНОВЛЕНИЯ http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html

1 голос
/ 23 июня 2011

Я бы сделал это за одну транзакцию, без возврата обратно на уровень приложения - и SELECT count() ...., и INSERT INTO отправляются в одной команде из PHP и встраиваются в TRANSACTION с EXCLUSIVE LOCK* 1005. *

...