Werzi2001
Werzi2001

Reputation: 2135

Why does a SELECT wait for a lock?

In my application I have the problem that sometimes SELECT statements run into a java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction exception. Sadly I can't create an example as the circumstances are very complex. So the question is just about general understanding.

A little bit of background information: I'm using MySQL (InnoDB) with READ_COMMITED isolation level.

Actually I don't understand how a SELECT can ever run into a lock timeout with that setup. I thought that a SELECT would never lock as it will just return the latest commited state (managed by MySQL). Anyway according to what is happening this seems to be wrong. So how is it really?

I already read this https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html but that didn't really give me a clue. No SELECT ... FOR UPDATE or something like that is used.

Upvotes: 1

Views: 4495

Answers (3)

Silva
Silva

Reputation: 1

If another process is updating the record and have not commit, your select READ_COMMITED will wait for that transaction to complete.

Upvotes: 0

Lukas
Lukas

Reputation: 451

To speed up queries in a DB, several transactions can be executed at the same time. For example if someone runs a select query over a table for the wages of the employees of a company (each employee identified by an id) and another one changes the last name of someone who e.g. has married, you can execute both queries at the same time because they don't interfere.

But in other cases even a SELECT statement might interfere with another statement.

To prevent unexpected results in a SQL transactions, transactions follow the ACID-model which stands for Atomicity, Consistency, Isolation and Durability (for further information read wikipedia).

Let's say transaction 1 starts to calculate something and then wants to write the results to table A. Before writing it it locks all SELECT statements to table A. Otherwise this would interfere with the Isolation requirement. Because if a transaction 2 would start while 1 is still writing, 2's results depend on where 1 has already written to and where not.

Now, it might even produce a dead-lock. E.g. before transaction 1 can write the last field in table A, it still has to write something to table B but transaction 2 has already blocked table B to read safely from it after it read from A and now you have a deadlock. 2 wants to read from A which is blocked by 1, so it waits for 1 to finish but 1 waits for 2 to unlock table B to finish by itself.

To solve this problem one strategy is to rollback certain transactions after a certain timeout. (more here)

So that might be a read on for your select statement to get a lock wait timeout exceeded.

But a dead-lock usually just happens by coincidence, so if transaction 2 was forced to rollback, transaction 1 should be able to finish so that 2 should be able to succeed on a later try.

Upvotes: 1

M.K
M.K

Reputation: 1495

That is probably due to your database. Usually this kind of problems come from that side, not from the programming side that access it.In my experience with db's, these problems are usually due to that. In the end, the programming side is just "go and get that for me in that db" thing.

I found this without much effort.

It basically explains that:

Lock wait timeout occurs typically when a transaction is waiting on row(s) of data to update which is already been locked by some other transaction.

You should also check this answer that has a specific transaction problem, which might help you, as trying to change different tables might do the timeout

the query was attempting to change at least one row in one or more InnoDB tables. Since you know the query, all the tables being accessed are candidates for being the culprit.

Upvotes: 1

Related Questions