2011-06-23 3 views
3

У меня есть код, как этотпараллелизм в InnoDB

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. как предотвратить это? транзакции, таблицы блокировки или что?

ответ

3

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

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

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

В качестве альтернативы, вы можете изменить ваш ВЫБРАТЬ быть SELECT ... FOR UPDATE http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html

+0

, нужно ли использовать функцию set tranaction перед выбором для обновления и вставки? – user677900

+0

Я думаю, да. «Блокировки, установленные в режиме LOCK IN SHARE MODE и FOR UPDATE, публикуются, когда транзакция совершена или откат». – user677900

1

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

+0

как установить монопольную блокировку ?. что, если 2 пользователя видят транзакцию в одно и то же время? – user677900

+1

Как указал Брент - «ЭКСКЛЮЗИВНЫЙ БЛОК» называется «ВЫБРАТЬ ... ДЛЯ ОБНОВЛЕНИЯ» в MySQL –

Смежные вопросы