2012-06-06 105 views
0

我正在为一个Silverlight应用程序创建一个WCF Web服务,并且我需要在修改时将一条记录读取/写入锁定。悲观锁定记录?

我正在使用MySQL版本5.5.11。

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

两个SQL的UPDATE命令和SELECT实际上是非常简单的,是这样的:

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

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; 
+1

为什么即使在交易中执行此操作? 'UPDATE'独立运行。也就是说,你所尝试的应该仍然有效;是什么让你觉得它没有? – eggyal

回答

0

你怎么确定它没有锁定记录?

当查询运行在带有锁的表上时,它将等待锁释放或最终超时。您的更新交易发生得如此之快,以至于您甚至无法分辨出它已被锁定。

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

我只是把它放在一个评论中,但它太长了,但我会根据你的回答更新一个更完整的答案。

+0

嗨, 应该在我原来的帖子中的SQL查询也阻止其他查询从这一行读取数据? 我的情况似乎发生了什么事情,即一条记录正在被修改过程中,另一条记录能够从中读取数据并/或返回旧值。这是一个Web应用程序,不知道它是否重要。 – SlashJ

+0

您的交易将持续一小会儿。另一个查询甚至能够在这个小时间内启动的可能性非常小。也许在更新事务开始之前,返回旧值的查询已启动。这听起来并不像你已经证实,这确实是问题,我的怀疑是你的问题在别处。 –

+0

@Armz此外,我不使用MySQL,所以我不是一个专家如何锁定,但我认为你可能会误解你什么时候需要使用FOR UPDATE。如果你只更新一个表格,那么行应该被锁定,你不需要自己锁定它们。问题出在您需要时,例如,在释放表上的锁之前确保发生多个任务。为了让行锁定在多个更新语句之间,您可以使用FOR UPDATE将它们锁定在整个时间。但是对于单个更新声明来说,我认为这是多余的,不必要的。 –

0

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