我有一个Java前端和一个MySQL后端场景,我在SELECT中使用了“LOCK IN SHARE MODE”。如果我从另一个进程请求相同的行,它会提供数据..但是它不允许我更新。我想要做的是通知用户他们只有一个只有READ的副本,所以如果他们希望看到他们可以的信息,他们可以在以后请求它。我怎么能检查ROW的状态,以便用户将被告知这种情况??如果我使用'FOR UPDATE',它只会等到第一个用户保存数据。我发现它不那么用户友好,如果他们只是一个空白的屏幕或当他们点击按钮它什么都不做。任何帮助将不胜感激。使用MySQL 5.5,Java 7。
答案 0 :(得分:1)
简短的回答是“你不能”!
您可能需要查看this discussion。
[编辑]
该帖子的答案指出:
你不能(检查锁的状态)是否有非命名锁!!!!更多信息: http://forums.mysql.com/read.php?21,222363,223774#msg-223774
行级锁不适用于应用程序级锁。它们只是实现一致读写的手段。这意味着你必须尽快释放它们。您需要实现自己的应用程序级别锁定,并没有那么难。也许一个简单的user_id
字段可以做到。如果它为null则没有锁定。但如果它不为null,则id表示谁持有该记录。在这种情况下,您需要行级锁定才能更新user_id
字段。正如我之前所说,只要你完成锁定/解锁记录,就必须释放MySQL锁。
答案 1 :(得分:0)
问题的全部前提在于相当自由地使用RDBMS'行级锁定(通常用于短期并发控制)直接用于交互式UI控制。
但是把它放在一边并回答问题,可以将会话的innodb_lock_wait_timeout
设置为非常短的值,最小值为1
,并捕获结果锁定等待超时超标;无法锁定时尝试重启事务。
当我尝试使用com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException
时,异常类为mysql-connector-java 5.1.38
,但其他异常类已经更改了版本,因此在旧版本的MySQL Connector / J中也可能有所不同。
"尝试和失败"获取锁的方法是解决这些类型的并发情况的标准方法,作为"在尝试之前检查的替代方法。是一种反模式,它在检查和实际锁定尝试之间创造了竞争条件。