Как реализовать блокировку базы данных для нескольких функций в модели воспламенителя кода? - PullRequest
4 голосов
/ 22 сентября 2011

Я создаю систему, которая включает в себя бронирование билетов многими пользователями в течение короткого периода времени с общим количеством возможных бронирований.Скажем, 600 доступных билетов, потенциально все они могут быть зарезервированы в течение 3 часов или менее.

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

Я пытаюсь использовать блокировки записи таблицы mysql дляОднако добиться этого я сталкиваюсь с проблемами при реализации этого в рамках codeigniter.В рамках этой модели я создал несколько функций, одну для создания резервирования и другие для подсчета количества билетов разных типов.Проблема в том, что они, похоже, не используют одни и те же сеансы базы данных, поскольку их функции подсчета билетов заблокированы.

Порядок выполнения:

  • run $ this->имя-модели-> create_reservation в контроллере
  • выполнить запрос блокировки в имени-модели-> create_reservation
  • метод подсчета вызовов в имени-модели-> create_reservation
  • функция подсчета (которая является методом в имени моделиclass) блокируется, предположительно потому, что используется другой сеанс базы данных?

Библиотека базы данных загружается в метод модели __construct с помощью $ this-> load-> database ();

Anyидеи?

1 Ответ

3 голосов
/ 22 сентября 2011

В mysql вы запускаете эти команды на дескрипторе БД перед выполнением запросов, таблицы автоматически блокируются:

begin work;

Затем вы выполняете свои запросы или запускаете различные варианты выбора и обновления, используя воспламенитель кода.db handle.

Тогда вы либо

commit;

, либо

rollback;

Любые выбранные вами строки будут заблокированы и не будут прочитаны другими процессами.Если вы хотите, чтобы строки по-прежнему читались, вы можете сделать следующее:

Select ... IN SHARE MODE

Из документации Mysql:

http://dev.mysql.com/doc/refman/5.5/en/select.html

Если вы используете FOR UPDATE смеханизм хранения, который использует блокировки страниц или строк, строки, проверенные запросом, блокируются на запись до конца текущей транзакции.Использование LOCK IN SHARE MODE устанавливает общую блокировку, которая позволяет другим транзакциям читать проверенные строки, но не обновлять или удалять их.См. Раздел 13.3.9.3, «ВЫБРАТЬ ... ДЛЯ ОБНОВЛЕНИЯ и ВЫБРАТЬ ... БЛОКИРОВКА В РЕЖИМЕ ОБЩЕГО ВРЕМЕНИ Блокировка чтения».

Другой человек уже сказал это в комментариях, но из документов CI:

$this->db->trans_start();
$this->db->query('AN SQL QUERY...');
$this->db->query('ANOTHER QUERY...');
$this->db->query('AND YET ANOTHER QUERY...');
$this->db->trans_complete(); 

trans_start и trans_complete будут выполнять эти запросы для вас на вашем дескрипторе ...

возможно, есть и trans_rollback ...

...