MySQL:我可以使用一个SELECT ... FOR UPDATE来“保护”多个表吗?(锁定)

佐尔坦

我正在阅读MySQL文档数小时,但仍然无法回答几个非常简单的问题... :(

这是我的(简化)方案:数据库中有两个表:tableatableb,两个表都使用InnoDB存储引擎。tablea(这是我的主表)具有id带有自动增量的PRIMARY索引()。现在,这是我要实现的目标,请记住,以下业务逻辑可以并且将同时运行:

我开始一个事务: START TRANSACTION BEGIN 然后检查是否存在id,tablea如果是,我选择行FOR UPDATE,让我们将其称为id,我正在寻找myid: SELECT `id` FROM `tablea` WHERE `id`='myid' FOR UPDATE; 如果上面的SELECT不返回任何行,我只是回滚事务并退出我的交易功能。换句话说,当myid不存在时,我就完成了tablea另一方面,当myid存在时,我首先需要更新中的一些值tablea UPDATE `tablea` SET `somefield`='somevalue' WHERE `id`='myid'; 然后我需要检查myid中是否还存在tableb SELECT * FROM `tableb` WHERE `id`='myid' FOR UPDATE; 我的第一个问题是关于上述SELECT语句的:是否可以在此处进行另一个SELECT FOR UPDATE?tableb)??? 或在进行处理时tableb此处不需要“ FOR UPDATE” ,因为我已经启动了事务并且还基于tablea???中的行获取了一个锁有人可以回答吗?

上面的最后一个SELECT语句返回一个行tableb(并锁定该行以进行更新),或者事实证明myid在中不存在tableb当myid存在时,tableb我只需要更新该行中的一些值,这很简单: UPDATE `tableb` SET `somefieldintableb`='somevaluefortableb' WHERE `id`='myid'; 另一方面,当myid不存在时,tableb我需要插入它,这是我的第二个问题:tableb在发出INSERT之前应该锁定吗?像这样的INTO语句: LOCK TABLES `tableb` WRITE; INSERT INTO `tableb` (`id`,`somefieldintableb`) VALUES ('myid','somevaluefortableb'); UNLOCK TABLES `tableb`; 然后最后,我这样做: COMMIT

我的目标是:由于上述函数(带有MySQL事务)将在许多实例中并行运行,因此我想防止这些实例中的任何一个在同一时间tableatableb同一时间更新同一行我还想防止将myid双重插入tableb,因此我考虑了在中找不到myid时使用LOCK TABLES tableb

所以我有两个问题:当我想用SELECT ... FOR UPDATE进行更新tableb或锁定时tableb是否应该在已启动的事务中执行SELECT ... FOR UPDATE,这是不必要的,因为也要同时锁定tablea已经“保护”的锁tableb在这种情况下的更新???多亏了我开始交易的方式,我的意思是。

第二个问题:当我需要在其中插入新行时,tableb是否应该锁定整个表以进行插入?还是在这种情况下完全不需要的东西?(我是否需要锁定表tableb?)

如果专家可以为我回答这两个问题,我将不胜感激,因为在线阅读各种文档和示例将完全无法帮助我回答这些问题。:(

比尔·卡文(Bill Karwin)

我会这样:

BEGIN;

SELECT a.`id` AS a_id, b.`id` AS b_id 
FROM `tablea` AS a LEFT OUTER JOIN `tableb` AS b ON a.id=b.id
WHERE a`id`='myid' 
FOR UPDATE;

现在你有两个表A和表B行锁,如果存在的行。如果SELECT不返回任何内容,则说明ID在表中不存在。如果SELECT返回的行的a_id值为,但b_id的值为NULL,则您知道它存在于tablea中,而不存在于tableb中。

如果在两个表中都存在该行,则这将同时锁定两个表中的行。如果分两步进行操作,则可能会面临竞争状况和死锁的风险。

尝试INSERT并使用ON DUPLICATE KEY UPDATE:

INSERT INTO `tableb` (id, somefieldintableb) VALUES ('myid', 'somevaluefortableb') 
ON DUPLICATE KEY UPDATE `somefieldintableb`='somevaluefortableb';

如果不存在具有所需id值的行,则将其插入。如果存在该行,则将更新该行。而且您肯定可以访问现有行,因为您的SELECT FOR UPDATE之前已将其锁定。

如果可以避免,请不要使用表锁。这是在应用程序中创建瓶颈的肯定方法。


对您的评论:

是的,您可以在日期列中使用额外的加入条件。

使用ON DUPLICATE KEY UPDATE时不必更新所有列。如果该行存在,您可以不理会它们中的大多数,而只更新其中的一个或几个。

您也可以引用您尝试插入的值

INSERT INTO `tableb` (id, date, col1, col2, col3, col4, col5, col6) 
  VALUES ('myid', $a_date, ?, ?, ?, ?, ?, ?) 
ON DUPLICATE KEY UPDATE col4=VALUES(col4);

有关更多详细信息,我建议阅读http://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

MySQL:我可以使用一个SELECT ... FOR UPDATE来“保护”多个表吗?(锁定)

来自分类Dev

我可以使用一个表来更新另一个表中的信息吗?

来自分类Dev

我可以使用一个select语句通过FK从2个表中获取多行吗

来自分类Dev

我可以使用一个表中的数据来更新另一表吗?

来自分类Dev

我可以使用联合来表达一个结构体和多个打包成员吗?

来自分类Dev

我可以使用变量模板来声明另一个变量模板吗?

来自分类Dev

我可以使用列表来寻址一个numpy数组吗?

来自分类Dev

我可以使用PropTypes来表示道具是一个Promise吗?

来自分类Dev

我可以使用变量模板来声明另一个变量模板吗?

来自分类Dev

我可以使用一个命令发送多个嵌入吗?Discord.js

来自分类Dev

我可以使用 Stream 将一个元素映射到多个元素吗?

来自分类Dev

我可以使用一个熊猫表作为另一个的映射表吗?

来自分类Dev

我可以使一个MySQL表的两个属性始终具有相同的值吗?

来自分类Dev

我可以使用一个控制器来更新AngularJS中的两个视图吗?

来自分类Dev

我可以使用gulp将内容从一个文件插入另一个文件吗?

来自分类Dev

我可以使用puttygen从最后一个公钥生成私钥吗?

来自分类Dev

我可以使用PropertyResourceConfigurer的setOrder方法覆盖另一个PropertyResourceConfigurer的属性吗?

来自分类Dev

我可以使用成员函数作为EnumWindows的第一个参数吗

来自分类Dev

我可以使用matplotlib应用程序分发一个额外的字体文件吗?

来自分类Dev

当杀死一个进程时,我可以使用它的`eax`保存退出状态吗?

来自分类Dev

我可以使用DataKinds编写一个返回参数编码类型的值的函数吗?

来自分类Dev

我可以使用变量的类型在Java中声明另一个变量吗?

来自分类Dev

我可以使用“包含页面”控件从另一个Db加载XPage吗?

来自分类Dev

我可以使用Cloud Dataproc Python API从本地系统上传一个Jar吗?

来自分类Dev

我可以使用.htaccess前置一个PHP文件吗?

来自分类Dev

我可以使用Tkinter创建一个Tcl交互式外壳吗?

来自分类Dev

我可以使用另一个#define指令重新定义宏吗?

来自分类Dev

我可以使用AutoMapper将一个int映射到对象列表吗?

来自分类Dev

我可以使用另一个类内部的函数中的变量吗?

Related 相关文章

  1. 1

    MySQL:我可以使用一个SELECT ... FOR UPDATE来“保护”多个表吗?(锁定)

  2. 2

    我可以使用一个表来更新另一个表中的信息吗?

  3. 3

    我可以使用一个select语句通过FK从2个表中获取多行吗

  4. 4

    我可以使用一个表中的数据来更新另一表吗?

  5. 5

    我可以使用联合来表达一个结构体和多个打包成员吗?

  6. 6

    我可以使用变量模板来声明另一个变量模板吗?

  7. 7

    我可以使用列表来寻址一个numpy数组吗?

  8. 8

    我可以使用PropTypes来表示道具是一个Promise吗?

  9. 9

    我可以使用变量模板来声明另一个变量模板吗?

  10. 10

    我可以使用一个命令发送多个嵌入吗?Discord.js

  11. 11

    我可以使用 Stream 将一个元素映射到多个元素吗?

  12. 12

    我可以使用一个熊猫表作为另一个的映射表吗?

  13. 13

    我可以使一个MySQL表的两个属性始终具有相同的值吗?

  14. 14

    我可以使用一个控制器来更新AngularJS中的两个视图吗?

  15. 15

    我可以使用gulp将内容从一个文件插入另一个文件吗?

  16. 16

    我可以使用puttygen从最后一个公钥生成私钥吗?

  17. 17

    我可以使用PropertyResourceConfigurer的setOrder方法覆盖另一个PropertyResourceConfigurer的属性吗?

  18. 18

    我可以使用成员函数作为EnumWindows的第一个参数吗

  19. 19

    我可以使用matplotlib应用程序分发一个额外的字体文件吗?

  20. 20

    当杀死一个进程时,我可以使用它的`eax`保存退出状态吗?

  21. 21

    我可以使用DataKinds编写一个返回参数编码类型的值的函数吗?

  22. 22

    我可以使用变量的类型在Java中声明另一个变量吗?

  23. 23

    我可以使用“包含页面”控件从另一个Db加载XPage吗?

  24. 24

    我可以使用Cloud Dataproc Python API从本地系统上传一个Jar吗?

  25. 25

    我可以使用.htaccess前置一个PHP文件吗?

  26. 26

    我可以使用Tkinter创建一个Tcl交互式外壳吗?

  27. 27

    我可以使用另一个#define指令重新定义宏吗?

  28. 28

    我可以使用AutoMapper将一个int映射到对象列表吗?

  29. 29

    我可以使用另一个类内部的函数中的变量吗?

热门标签

归档