2

in my project using java, ibatic and MySql.

Before any updating data into database, i lock the table with SELECT FOR UPDATE query

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

It make locking the table properly. but the problem is, for example if two client are update the table in same time. first one is lock the table and update but second one is waiting to update until a lock is released. After then second one also update the data. So, first one updated data is overwrite. Please see the following explanation:

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

So, Client 1 updated data is lost

What I want to be is want to simply return the error message to Client 2 instead of waiting until a lock is released.

Please advise me the way to solve above mentioned problem.


P.S:

I already set the lock wait timeout to 0 in startup Variables, but it still take about 2 second to tell "Lock wait timeout exceeded" message.

furthermore,SELECT FOR UPDATE NO WAIT is not working in MySQL

4

1 回答 1

0

不幸的是,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;
于 2013-12-19T17:22:58.983 回答