首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >mysql中间地带锁在共享模式和锁之间进行更新?

mysql中间地带锁在共享模式和锁之间进行更新?
EN

Stack Overflow用户
提问于 2011-11-01 15:53:49
回答 2查看 622关注 0票数 1

我试图在锁定共享模式和锁进行更新之间找到一个中间点。

看起来,只要未更新要修改的行,共享模式就可以由两个不同的事务获取。这在下面的场景中很糟糕:

  • t1开始
  • X上的t1读锁
  • t2开始
  • X上的t2读锁
  • t2检查X.foo == 0
  • t1更新X.foo =1
  • t1结束
  • t2继续使用坏逻辑,因为X.foo != 0

我可以使用的替代方法是锁定更新,但这对我的应用程序来说太过限制,因为我不在乎我的用户是否读取了10秒的值。所以我从来不想用锁来更新。

问:我是否可以使用这样的锁:

  1. 是排他的
  2. 允许在不获取锁的情况下读取行。

示例:

  • t1 my_lock行X
  • 不允许t2 my_lock行X =>
  • t3选择允许的X行=>,返回最新提交的数据,如锁共享模式

编辑:我使用NDB集群作为我的存储引擎。服务器版本:5.1.56-ndb-7.1.15a-集群-GPL-日志MySQL群集服务器(GPL)

EN

回答 2

Stack Overflow用户

发布于 2011-11-01 16:19:09

不知道你在做什么,很难准确地知道你在做什么。但这里有几个提示,可以帮助你找到答案。

首先,普通SELECT ... FROM ...不对任何行执行锁定,并提供一致的读取--也就是说,它根据SELECT语句开始时数据库中的内容提供一个结果集。

这一点很重要,因为锁定时间的唯一问题是:

  • 多个语句同时尝试更新相同的数据,或者
  • 出于某种原因,您希望在长SELECT语句的中间所做的更新能够反映在结果中。(我不知道为什么这是正确的。)

其次,为其他类型的语句(例如,SELECT ... FROM ... LOCK IN SHARE MODE)锁定的行将取决于用于选择要更新的行的索引。基本上,为定位行而扫描的索引的所有行都将被锁定。

这一点至关重要,因为您可以通过手工索引大大减少锁定的行数,这些索引允许UPDATE语句选择要直接更新的行。例如,如果可以在表上创建一个UNIQUE索引,然后在运行更新时让update语句点击该索引,那么只有该行将被锁定。

所以我遇到的最幸运的问题是获取了这两条信息-- 1)普通选择不执行任何锁定,2)我可以定义好的索引来最小化实际被锁定的行-然后设计不导致锁定冲突的sql。

这里有一个指向一个页面的链接,它总是帮助我解决任何与锁定有关的问题。它具体描述了生成锁的每种语句以及它们是什么类型的锁:由InnoDB中不同的SQL语句设置的锁

票数 1
EN

Stack Overflow用户

发布于 2011-11-01 15:59:58

你用的是MyISAM还是InnoDB?我建议使用InnoDB和使用MVCC的事务隔离级别来实现所需的并发级别。

由于MVCC,InnoDB中的正常选择不会锁定。这样你就不会阻止读者了。

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

https://stackoverflow.com/questions/7969096

复制
相关文章

相似问题

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