如何在代码点火器模型中跨多个函数实现数据库锁定?

Posted

技术标签:

【中文标题】如何在代码点火器模型中跨多个函数实现数据库锁定?【英文标题】:How to implement database locking across several function in a code igniter model? 【发布时间】:2011-11-22 09:28:06 【问题描述】:

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

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

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

执行顺序是

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

在模型__construct方法中用$this->load->database()加载数据库库;

有什么想法吗?

【问题讨论】:

我对CI不熟悉,但是解决方法是使用transactions。我想 CI 提供了开始/结束事务的方法,我会调查一下。 codeigniter.com/user_guide/database/transactions.html 【参考方案1】:

在 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 锁定读取”。

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

【讨论】:

干杯扎克!检查我是否正确理解这一点,您可以使用事务,该事务将像我在原始帖子中建议的那样锁定到位,但比直接使用锁定更有好处?所以我认为 codeigniter 将支持在模型内的方法调用之间共享相同的事务,但不支持共享普通锁?

以上是关于如何在代码点火器模型中跨多个函数实现数据库锁定?的主要内容,如果未能解决你的问题,请参考以下文章

在 scikit-learn 中跨多个模型进行交叉验证时如何保持相同的折叠?

在 Swift 中跨多个选项卡访问相同的视图模型

BigQuery SQL 中跨多个字段的拆分函数

创建数据表,将数据传递给视图代码点火器

Javascript中跨多个文件的全局变量

如何在 youtube api 中跨多个频道搜索内容?