4

我正在创建一个系统,该系统涉及许多用户在短时间内预订门票,总共只能进行一定数量的预订。假设有 600 张门票可用,可能全部在 3 小时或更短的时间内预订。

理想情况下,我想确保未达到预订限制,因此在创建预订之前,我会检查是否可以根据可用门票数量进行预订。至关重要的是,我需要确保在检查和将票证分配给用户之间没有发生更新,以确保不会超过票证限制。

我正在尝试使用 mysql 表写入锁来实现这一点,但是在 codeigniter 框架中实现这一点时遇到了问题。在处理这个问题的模型中,我创建了几个函数,一个用于创建预订,另一个用于计算不同类型门票的数量。问题是他们似乎没有共享相同的数据库会话,因为他们的票务计数功能正在锁定。

执行顺序是

  • 在控制器中运行 $this->model_name->create_reservation
  • 在 model_name->create_reservation 中运行锁定查询
  • 在 model_name->create_reservation 中调用计数方法
  • 计数函数(这是model_name类中的一个方法)锁定,大概是因为使用不同的数据库会话?

数据库库通过 $this->load->database() 加载到模型的 __construct 方法中;

有任何想法吗?

4

1 回答 1

3

在 mysql 中,在运行查询之前在数据库句柄上运行这些命令,表将自动锁定:

begin work;

然后,您运行您的查询或让代码点火器使用该数据库句柄运行您的各种选择和更新。

那你要么

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 节,“SELECT ... FOR UPDATE 和 SELECT ... LOCK IN SHARE MODE 锁定读取”。

另一个人已经在评论中说过这一点,但来自 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 ......

于 2011-09-21T23:48:03.407 回答