MySQL Forums
Forum List  »  NDB clusters

Lock wait timeout exceeded; try restarting transaction - Multi thread application
Posted by: Dev Das
Date: August 31, 2015 05:05PM

MySQL server: 5.6.15
MySQL Cluster: 7.3.4

Running production multi-threaded application, with optimized queries - intermittently receiving "Lock wait timeout exceeded; try restarting transaction". The scenario has been filtered to 2 tables, and separate threads when they are accessing (SELECT and UPDATE) the same row of data on each table.

Application being a telecom application, the response time is very important, and keeping that in view, the connection timeout is set to 2 seconds and the command timeout is set to 2 seconds. "Lock wait timeout" is captured couple of time a day, and is not time dependent. Under production once MySQL ADO connection throws the exception; Dot Net application captures the exception, and re-runs the query and everything works fine.

I am planning to find a solution where the "wait lock" can be removed completely, or to get a better control, so to avoid the scenario (if possible).

Individual queries causing the "lock":
Query #1:
SELECT a_ID, Gender,
IFNULL( ( SELECT a.Id FROM acct AS a WHERE a.Acc_Number = '231652' AND Grp_Id = '1' LIMIT 1), 0) AS AId2,
IFNULL( ( SELECT Port FROM lusers AS l WHERE l.Acc_Number = '231652' AND l.Grp_Id = '1' LIMIT 1), 1000) AS Port2
FROM lusers WHERE Port = '1391' LIMIT 1;

Query #2:
UPDATE lusers AS l INNER JOIN acct as a ON l.a_Id = a.Id
SET l.Screen = '3', a.ScreenStatus = '3'
WHERE a.Id = '2';

My understanding:
Transaction A locks row #1
Transaction B locks row #2
Transaction A tries to lock row #1, but can't
Transaction B tries to lock row #2, but can't
Both transactions wait until "lock wait timeout kicks in"

To create the sample database with data, run the following:
DROP TABLE IF EXISTS acct;
CREATE TABLE acct (
Id int(11) NOT NULL AUTO_INCREMENT,
Acc_Number int(11) NOT NULL DEFAULT '0',
Grp_Id smallint(6) NOT NULL DEFAULT '0',
ScreenStatus int(1) NOT NULL DEFAULT '0',
PRIMARY KEY (Id),
UNIQUE KEY GrpId_AccNumber (Grp_Id, Acc_Number)
) ENGINE=ndbcluster;

DROP TABLE IF EXISTS lusers;
CREATE TABLE lusers (
Id int(11) NOT NULL AUTO_INCREMENT,
a_Id int(11) NOT NULL DEFAULT '0',
Acc_Number int(11) NOT NULL DEFAULT '0',
Grp_Id smallint(6) NOT NULL DEFAULT '0',
Port int(11) NOT NULL DEFAULT '0',
Gender int(1) NOT NULL DEFAULT '0',
Screen int(1) NOT NULL DEFAULT '0',
PRIMARY KEY (Id),
UNIQUE KEY GrpId_AccNumber (Grp_Id, Acc_Number),
UNIQUE KEY a_Id (a_Id),
UNIQUE KEY Port (Port)
) ENGINE=ndbcluster;

INSERT INTO acct (Acc_Number, Grp_Id, ScreenStatus ) VALUES ('231652', '1', '3');
INSERT INTO acct (Acc_Number, Grp_Id, ScreenStatus ) VALUES ('123456', '1', '3');
INSERT INTO lusers (a_Id, Acc_Number, Grp_Id, Port, Gender, Screen) VALUES ('1', '231652', '1', '1234', '1', '3');
INSERT INTO lusers (a_Id, Acc_Number, Grp_Id, Port, Gender, Screen) VALUES ('2', '123456', '1', '1345', '0', '3');

SELECT a_ID, Gender, IFNULL( ( SELECT a.Id FROM acct AS a WHERE a.Acc_Number = '231652' AND Grp_Id = '1' LIMIT 1), 0) AS AId2, IFNULL( ( SELECT Port FROM lusers AS l WHERE l.Acc_Number = '231652' AND l.Grp_Id = '1' LIMIT 1), 1000) AS Port2 FROM lusers WHERE Port = '1391' LIMIT 1;

UPDATE lusers AS l INNER JOIN acct as a ON l.a_Id = a.Id SET l.Screen = '3', a.ScreenStatus = '3' WHERE a.Id = '2';

EXPLAIN SELECT a_ID, Gender, IFNULL( ( SELECT a.Id FROM acct AS a WHERE a.Acc_Number = '231652' AND Grp_Id = '1' LIMIT 1), 0) AS AId2, IFNULL( ( SELECT Port FROM lusers AS l WHERE l.Acc_Number = '231652' AND l.Grp_Id = '1' LIMIT 1), 1000) AS Port2 FROM lusers WHERE Port = '1391' LIMIT 1;
+----+-------------+--------+--------+-----------------+-----------------+---------+-------------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+--------+-----------------+-----------------+---------+-------------+------+-------+
| 1 | PRIMARY | lusers | eq_ref | Port | Port | 4 | const | 1 | NULL |
| 3 | SUBQUERY | l | eq_ref | GrpId_AccNumber | GrpId_AccNumber | 6 | const,const | 1 | NULL |
| 2 | SUBQUERY | a | eq_ref | GrpId_AccNumber | GrpId_AccNumber | 6 | const,const | 1 | NULL |
+----+-------------+--------+--------+-----------------+-----------------+---------+-------------+------+-------+

EXPLAIN UPDATE lusers AS l INNER JOIN acct as a ON l.a_Id = a.Id SET l.Screen = '3', a.ScreenStatus = '3' WHERE a.Id = '2';
+----+-------------+-------+--------+---------------+---------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+---------+---------+-------+------+-------------+
| 1 | SIMPLE | l | eq_ref | a_Id | a_Id | 4 | const | 1 | NULL |
| 1 | SIMPLE | a | eq_ref | PRIMARY | PRIMARY | 4 | const | 1 | Using where |
+----+-------------+-------+--------+---------------+---------+---------+-------+------+-------------+

Options: ReplyQuote


Subject
Views
Written By
Posted
Lock wait timeout exceeded; try restarting transaction - Multi thread application
3011
August 31, 2015 05:05PM


Sorry, you can't reply to this topic. It has been closed.

Content reproduced on this site is the property of the respective copyright holders. It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.