问题标签 [table-locking]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
25 浏览

mysql - 无法通过 mysql 命令行手动将读取或写入锁应用于 Innodb 表

我正在尝试在表格锁定的情况下测试一个场景。

我试图应用这样的读写锁 -

但在此之后能够写 -

读锁也不起作用。应用锁定后,我能够成功执行选择查询。

当我们对大量数据进行表迁移时,我需要测试我的应用程序行为(restful API),此时表上可能应用了写锁。所以,我想,如果我能够通过命令行设置锁,它也将适用于我的 API。我使用相同的用户登录命令行,就像我在应用程序中使用登录mysql一样。

如果我遗漏了什么,请告诉我。

该表是 InnoDb 类型的。

0 投票
2 回答
650 浏览

mysql - 简单插入期间的innodb全表锁

我们的代码确实

这样的插入在多个服务器上并行运行并且具有高并发(有时甚至在 2 个并行),其中许多由于锁定等待超时而失败。显示 innodb 状态如下所示

我们在 mysql 8.0.13 上,innodb_autoinc_lock_mode 设置为引擎默认值(2 交错),这是最轻松的模式。我们在代码中没有使用 MySQL 级别的 LOCK TABLE,所以我们很困惑为什么 innodb 在 IX 模式下会锁定完整的用户表?表格如下所示

usertbl_user_id_account_id_idx 是必需的,因为很少有表在用户表中有外键,如下所示

0 投票
1 回答
252 浏览

php - PDO 一般错误:2014 无法执行查询,而其他无缓冲查询在尝试锁定表时处于活动状态

我正在将某人的旧代码从 using 更新mysql()为 using PDO。在一个地方,他们有一些LOCK TABLES命令来防止两个用户同时访问相同的数据。运行时LOCK TABLESPDO抛出“一般错误:2014 无法在其他无缓冲查询处于活动状态时执行查询”。

我做了一些测试代码来消除其他变量。系统在 Ubuntu 18 / PHP 7.2 / MySQL 5.7.27 上运行:

我也尝试在$_DB->beginTransaction之前LOCK TABLES$_DB->commit之后添加一个UNLOCK TABLES,但我仍然得到同样的错误。

我尝试了 and 的各种组合ATTR_EMULATE_PREPARESMYSQL_ATTR_USE_BUFFERED_QUERY但似乎没有任何区别。

0 投票
2 回答
3249 浏览

php - 同一行上的多个 Update 语句

我有一个场景,我从客户那里收到了出租车请求,然后我向多个司机发送了取货请求。现在想象一下,如果两个收到请求的司机同时点击“接受”按钮,那么哪个司机会搭车。

我有一个包含ride_id、driver_id、已完成(布尔)列的乘车表。

到目前为止,我正在做的是在点击“接受”按钮后立即调用 API。此 GET 请求 API 检查行程是否已完成。如果是,我会向司机显示一​​条消息,说乘车已经完成,否则我会点击另一个 POST API 请求,它将 DB 中的已完成值更新为 true,并更新 driver_id。

现在进入我们的场景,当两个驱动程序同时点击“接受”时,将发出两个 GET 请求,并且两者都将得到“未完成”作为响应,此后两者都将发送一个 POST 请求。现在我很困惑谁的数据将在数据库中更新。

我在后端使用 PHP 和 MYSQL 作为数据库。

0 投票
1 回答
1265 浏览

sql - 如何防止多个用户同时写入和读取表的表锁定?

我有一个我为一个小组编写的程序,该小组在每个用户的每个会话中不断向我们的 SQL 服务器写入、读取和删除。我不需要担心正在写入或删除的内容,因为一个人正在写入/删除的所有数据都不会被另一个人需要。每个用户写入由唯一 ID 分隔,所有查询都基于该唯一 ID。

我希望能够同时由多个用户从同一个表中写入/删除行。我知道我可以将会话设置为能够在使用SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED.

问题:

也就是说,我可以让多个用户同时从同一个表中写入/删除吗?

目前,如果这不可能,我唯一的想法是设置工具以写入每个用户会话的临时表。但我认为这不是每天数百次不断创建和删除临时表的有效选择。

0 投票
1 回答
102 浏览

mysql - 在 MySQL 5.7 中混合事务和表锁是不现实的吗?

我希望在 API 中混合表锁和事务。我选择了 MySQL 5.7 作为存储引擎,尽管我并不特别致力于任何特定的 RDBMS。在深入研究之前,我有兴趣了解我当前的设计是否适合 MySQL。

在我的设计中,我有三个表:

  • expenditure( id, amount, title)
  • donation( id, amount, title)
  • contribution( id, amount, expenditure_id, donation_id)

如您所见,这是两个表之间的简单多:多,contribution作为桥接表。我已经设置了约束,以便强制执行这种关系。

该应用程序基本上是一个慈善机构的会计程序 - 管理员创建捐赠条目(来自捐赠者的钱)和支出(用于慈善目的的钱)。管理员有时会通过在桥接表中创建条目来将捐款分配给支出。大额捐款可以用于几笔支出,大笔支出会消耗几笔捐款。

我感兴趣的是如何在 MySQL 中创建这些桥接条目。我想我会有一个像这样的伪代码的函数:

因此,假设我的支出为 5000,并且我有两笔捐款(id 1 和 2),金额分别为 3000 和 2500。我想要 3000(所有第一次捐款)和 2000(部分第二次捐款)的捐款。贡献行如下所示:

我有一些相关的观察:

  • 我有一些验证要做,例如确保捐款没有附加到其他地方
  • 我希望能够在出现错误的情况下回滚
  • 我希望我的验证在编写这些记录期间保持真实,即防止在检查数据库和编写记录之间出现竞争条件
  • 我认为这意味着我想在中央表上写一个表锁

这是我的代码粗略草图(节点,但语言无关紧要):

该手册给出了这个建议

将 LOCK TABLES 和 UNLOCK TABLES 与事务表(例如 InnoDB 表)一起使用的正确方法是使用 SET autocommit = 0(不是 START TRANSACTION)开始事务,然后是 LOCK TABLES,并且在提交事务之前不要调用 UNLOCK TABLES明确的

但是它也说(在同一页面上):

LOCK TABLES 不是事务安全的,并且在尝试锁定表之前隐式提交任何活动事务

所以,我认为这些东西是不相容的。我想使用事务以便在出现问题的情况下能够回滚,这样数据库就不会处于不一致的状态。我还想使用写锁,以便我的验证在表被解锁之前保持正确,否则可能会发生竞争条件,从而超支捐赠(由于另一个用户分配了相同的捐赠之一)。

但是如果LOCK TABLES提交一个开放的事务,那么我会不会有这种情况(时间向下流动)?

我想知道这里发生了什么,lock tables因为用户 2 对用户 1 的事务进行了隐式提交,rollback用户 1 没有进行完全回滚,因为已经发出了一些提交。

或者用户 2 的锁表是否基于另一个会话具有表锁而强制等待,并且它暂停操作直到用户 1 释放锁?

0 投票
1 回答
147 浏览

oracle - 修改父表中的数据时,Oracle 子表的行为如何?

场景:我们有表 A(父表)引用表 B(子表),并且我们有每个外键的外键索引。

操作:现在当任何用户从表 A 中删除一行时,即使子表中没有引用记录,表 B 也会被锁定。由于该表已锁定,因此其他用户无法再对表 A 执行任何操作。

理解:我想当表B中存在一些子记录时,只有当父记录涉及某些事务并且其他用户仍然可以在表A的其他行上工作时,才应该锁定所选行。

问题:当我们有外键并且创建了外键索引但没有子记录存在时,它是如何工作的。整张桌子还锁着?如果是的话如何摆脱它呢?

注意:我使用的是 Oracle 12c。

0 投票
1 回答
285 浏览

mysql - 更改期间外键表上的 Mysql 8 元数据锁定

当我执行alter table命令时,我会遇到很多死锁。where 命令位于waiting for metadata lock不属于 alter table 语句的表上。这些表通过外键链接,但我们没有更改外键。

有没有办法在不让mysql屈服的情况下运行alter tables?

最小的例子

给定这两个表表有外键关系。

当连接读取一些数据时,它会获取元数据锁。

然后一个单独的连接尝试在父表上运行一个 alter 语句。即使我们没有接触孩子或 id,这也需要对孩子进行元数据锁定。

我们可以看到这些锁

生产中的死锁

在我们有更多表和外键的生产系统中,我们看到死锁,其中更改表为表 A 获取锁但无法获取表 B。表 B 被需要表 A 的线程锁定。对我们来说有点竞争条件,但由于 mysql 需要锁定所有链接表而不仅仅是一个正在改变的表,从而加剧了这种情况。

这似乎是 mysql 8 的新行为。我希望我没有升级。我们在带有 innodb 表的 mysql 8.0.20 上。

有没有办法在不锁定数据库的情况下运行这些更改?理想情况下,我想保留我的外键,我不想使用像 Percona 这样的迁移管理器。我的桌子甚至没有那么大。

谢谢

0 投票
1 回答
855 浏览

indexing - 在没有表锁定的巨大 MariaDB 生产数据库中创建索引

我有一个包含 202M 记录的表,我需要在其中添加一些索引,如果在 MariaDB 10.3 中可以在不锁定的情况下这样做,我在任何地方都找不到它(或者我可能不懂术语)。

我发现了这篇文章,我可以看到这在 MySQL 5.6+ 中是可能的,但是我的 google foo 没有得到我关于 MariaDB 的任何信息。

我尝试使用 pt-online-schema-change 但由于我没有任何不是选项的索引(甚至不是主索引)。

0 投票
2 回答
56 浏览

mysql - 一般 InnoDB UPDATE 是否会锁定整个表并阻止传入的特定 UPDATE?

假设我运行了这个语句:

在 InnoDB 表上,Employees,大约有 1000 万行。

其他用户也通过如下 SQL 查询积极更新此表:

例如,一个用户,ID = 20,将他们的国家更改为 NZ:

  1. 在这种情况下,在一般更新完成之前,是否会阻止对该表的任何进一步更新?
  2. 如果是这样,有没有办法允许特定更新和一般更新同时运行,如果它们没有更新同一行?(为了澄清我的意思:假设一般更新完成了对 ID 为 1 - 50 的员工的更新,现在正在更新员工 51 - ~ 1000 万,对于 ID 为 20 的员工的单一更新应该在不等待一般更新的情况下完成完成)