【问题标题】:Pessimistic locking of record?悲观锁定记录?
【发布时间】:2012-06-06 17:50:12
【问题描述】:

我正在为 Silverlight 应用程序创建 WCF Web 服务,并且我需要有一条记录在修改时被读/写锁定。

我使用的是 MySQL 5.5.11 版。

更具体地说,我想阻止请求在修改行时从行中读取数据。

UPDATE 和 SELECT 的两个 SQL 命令实际上非常简单,类似于:

更新(应该锁定写/读):

UPDATE user SET user = ..... WHERE id = .....

选择(从上面的查询中锁定时应该无法读取):

SELECT * FROM user WHERE id = .....

这是我尝试过的,但它似乎根本不起作用或锁定任何东西:

START TRANSACTION;
   SELECT user
   FROM user
   WHERE id = 'the user id'
   FOR UPDATE;

   UPDATE user
   SET user = 'the user data'
   WHERE id = 'the user id';
COMMIT;

【问题讨论】:

  • 为什么还要在事务中执行此操作? UPDATE 以原子方式自行运行。也就是说,你正在尝试的应该仍然有效;是什么让你认为它没有?

标签: c# mysql pessimistic-locking rowlocking


【解决方案1】:

您如何确定它没有锁定记录?

当对一个带有锁的表运行查询时,它将等待锁被释放或最终超时。您的更新事务会发生得如此之快,以至于您甚至无法判断它已被锁定。

您能够判断存在问题的唯一方法是,如果您有一个在事务开始后运行的查询,但返回的是用户的原始值而不是更新后的值。有没有发生过?

我本来想把它放在评论中,但它太长了,但我会根据你的回复用更完整的答案更新它。

【讨论】:

  • 嗨,我原来的帖子中的 SQL 查询是否也应该阻止其他查询从该行读取数据?在我的情况下似乎发生的是,当一条记录正在被修改时,另一条记录能够从中读取数据和/或返回旧值。这是一个web应用,不知道有没有关系。
  • 您的交易将持续不到一秒。甚至能够在这么短的时间内启动另一个查询的可能性很小。也许返回旧值的查询在您的更新事务开始之前开始。听起来您尚未验证这确实是问题所在,我怀疑您的问题出在其他地方。
  • @Armz 另外,我不使用 mysql,所以我不是它如何锁定的专家,但我认为您在需要使用 FOR UPDATE 时可能会误解。如果您只更新一个表,那么应该锁定行,您不需要自己锁定它们。问题在于,例如,当您需要确保在释放表上的锁之前发生多个任务时。要在多个更新语句之间保持行锁定,您可以使用 FOR UPDATE 使它们始终保持锁定。但对于单个更新语句,我认为这是多余且不必要的。
【解决方案2】:

MySql 使用多版本并发控制by default(这是一个非常非常好的行为,而不是 MSSQL)。尝试使用locking reads(锁定共享模式)来实现您想要的。

【讨论】:

    猜你喜欢
    • 2013-02-07
    • 2010-09-12
    • 2014-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-22
    • 1970-01-01
    相关资源
    最近更新 更多