首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于写入但允许读取的InnoDB表锁

用于写入但允许读取的InnoDB表锁
EN

Stack Overflow用户
提问于 2017-10-19 00:14:50
回答 1查看 62关注 0票数 0

我有一个表COMMANDS,用户可以同时插入数据。

每次插入后,我必须进行一些(耗时的)计算,并将结果保存到另一个表RESULTS中。

同时,所有用户也会从COMMANDS中读取数据。

我的问题是:

在插入新的$command之后,我在计算中使用该表中的所有行。每一行都会影响计算,也可能会影响以前的$commands,因为我想锁定这个表以进行新的插入,直到当前计算完成并保存结果。但我也不想阻止其他用户查看COMMANDS的当前状态。

不久,我想要锁定一个表以供写入,而不锁定以供读取。

我使用的是InnoDB引擎。我读了一些关于锁定的文档,但我完全搞混了。

共享和排他锁,意向锁,缝隙锁...

这看起来很愚蠢,但目前我正在使用下面这样的机制

代码语言:javascript
复制
public function storeNewCommand($command){

    // $busy_flag is an app level global that can be read by all user sessions

    if($busy_flag){
        usleep(10000);
        return $this->storeNewCommand($command);
    } 

    $busy_flag = true; //(lock)

    /*
    ...insert new $command to COMMANDS

    ...do calculations using all comands including last one

    ...store results in RESULTS
    */

    $busy_flag = false; //(unlock)

}

我知道一定有更好、更聪明的解决方案来解决这个问题,而不需要循环和睡眠。但我不知道该用哪一个。

EN

回答 1

Stack Overflow用户

发布于 2017-10-19 00:52:37

如果您可以在少于lock_wait_timeout的时间内完成冗长的工作,那么可以使用BEGIN...COMMIT。(就我个人而言,我会将其限制在2秒内,而不是50秒。)

否则,设计一些其他的方法--有一个每个作者都尊重的表,说你在这个“关键部分”是“忙”的。它可能不需要多于1列或2列的单行表格。

在获取互斥锁时,请确保将fetch、set等封装在事务中,并对失败做出反应。在获得锁之后,然后继续执行较慢的操作。最后释放锁。

注意:如果发生崩溃或软件错误,释放锁的代码可能永远不会执行。因此,最好包括一个时间戳,再加上一些需要注意的东西,即互斥锁已经很长一段时间没有被释放了。它可以让他们给你发邮件告诉你这个问题,并清除锁。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46814716

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档