java - MySQL不等待返回物理锁错误的方法

标签 java mysql locking sql-update ibatis

在我的项目中使用 java、ibatic 和 MySql。

在将任何数据更新到数据库之前,我使用 SELECT FOR UPDATE 查询锁定表

eg: SELECT * FROM MEM_MST WHERE MEM_ID = #memId# FOR UPDATE

它使表正确锁定。但问题是,例如,如果两个客户端同时更新表。第一个是锁定表并更新,但第二个是等待更新,直到释放锁。然后第二个也更新数据。因此,第一个更新的数据被覆盖。请看下面的解释:

Time |  Client 1           | Client 2  
-------------------------------------------------
1    | SELECT FOR UPDATE   | 
2    | UPDATE              | SELECT FOR UPDATE (Waiting) 
3    | COMMIT              | (Waiting)
4    |                     | UPDATE
5    | (Overwritten)       | COMMIT

所以,客户端1更新的数据丢失了

我想做的是简单地将错误消息返回给客户端 2,而不是等到锁被释放。

请告诉我解决上述问题的方法。


附言:

我已经在启动变量中将锁定等待超时设置为 0,但仍然需要大约 2 秒才能告知“超出锁定等待超时”消息。

此外,SELECT FOR UPDATE NO WAIT 在 MySQL 中不起作用

最佳答案

不幸的是,innodb_lock_wait_timeout不能设置为低于 1。

您必须实现自己的同步机制。作为 eggyal 建议的替代方案,您可以在关键表中添加一个“信号量”字段。基本工作流程(伪代码):

START TRANSACTION;
SELECT locked FROM MEM_MST WHERE MEM_ID = @id FOR UPDATE;
if (previous_result == 1) {
    ROLLBACK;
    throw new Exception();
}
UPDATE MEM_MST SET locked = 1 WHERE MEM_ID = @id;
COMMIT; -- from now on, concurrent attempts will fail immediately

START TRANSACTION;
UPDATE MEM_MST SET whatever = @some_value WHERE MEM_ID = @id;
UPDATE MEM_MST SET locked = 0 WHERE MEM_ID = @id; -- release lock
COMMIT;

关于java - MySQL不等待返回物理锁错误的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10562024/

相关文章:

php - 我如何使用 PHP 从 mysql 数据库中检索和显示时间戳?

php - 如何使用 MySQL 中的报告子查询优化多个连接的查询

sql-server - 休眠/SQL Server : default lock mode

database - "no such table"内存中 sqlite 错误

java.lang.UnsatisfiedLinkError : C:\Program Files (x86)\IBM\Lotus\Notes\nlsxbe. dll AMD 64 位平台上的 : Can't load IA 32-bit . dll

Java Apache CLI 可选命令行参数不起作用

java - 学习 "large-scale"Java技术

php - MySQL 优化数据库中的数据存储,当条目更改时

c# - 仅当线程处于某个方法时才锁定多个方法

java - 返回客户端时 CXF WS 调度失败