views:

242

answers:

3

In my client application I have a method like this (in practice it's more complex, but I've left the main part):

public void btnUpdate_Click(...)
{
  ...
  dataAdapter.Update(...);
  ...
  dataAdapter.Fill(...); // here I got exception one time
}

The exception I found in logs says "Deadlock found when trying to get lock; try restarting transaction". I met this exception only time, so it wasn't repeated.
As I understand, DataAdapter.Fill() method executes only select query. I don't make an explicit transaction and I have autocommit enabled.
So how can I get dead lock on a simple select query which is not a part of bigger transaction?
As I understand, to get a dead lock, two transactions should wait for each other. How is that possible with a single select not inside a transaction? Maybe it's a bug in MySql?

Thank you in advance.

A: 

You are right it takes two transactions to make a deadlock. That is to say, No statement or statements within a single transaction can deadlock with other statements within the same transaction.

But it only take one transaction to notice a report of a deadlock. How do you know that the transaction you are seeing the deadlock reported in is the only transaction being executed in the database? Isn't there other activity going on in this database?

Also. your statement "I don't make an explicit transaction", and "... which is not a part of bigger transaction" implies that you do not understand that every SQL statement executed is always in an implicit transaction, even if you do not explicitly start one.

Most databases have reporting mechanisms specifically designed to track, report and/or log instances of deadlocks for diagnostic purposes. In SQL server there is a trace flag that causes a log entry with much detail about each deadlock that occurs, including details about each of the two transactions involved, like what sql statements were being executed, what objects in the database were being locked, and why the lock could not be obtained. I'd guess mySQL has similar disgnostic tool. Find out what it is and turn it on so that the next time this occurs you can look and find out exactly what happened.

Charles Bretana
'Also. your statement "I don't make an explicit transaction", and "... which is not a part of bigger transaction" implies that you do not understand that every SQL statement executed is always in an implicit transaction, even if you do not explicitly start one." - This is a wrong conclusion. I clearly know it. I asked if there is anything to help track/log/understand deadlocks in mysql on mysql forum. Let's see. But you didn't say how I could get a deadlock. Can you show an example with simple select statement (and nothing else in this transaction) getting deadlocked?
nightcoder
A: 

You can deadlock a simple SELECT against other statements, like an UPDATE. On my blog I have an example explaining a deadlock between two well tunned statements: Read/Write deadlock. While the example is SQL Server specific, the principle is generic. I don't have enough knowledge of MySQL to claim this is necessarily the case or not, specially in the light of various engines MySQL can deploy, but none the less a simple SELECT can be the victim of a deadlock.

Remus Rusanu
Just to be clear, you can deadlock a Select against other statements in ANOTHER transaction, not with other statements in the SAME transaction...
Charles Bretana
A: 

I haven't looked into how MySQL transaction works, but this is based on how MSSQL transactions work:

If you are not using a transaction, each query has a transaction by itself. Otherwise you would get a mess every time an update failed in the middle.

The reason for the deadlock might be lock escalation. The database tries to lock as little as possible for each query, so it starts out by locking only the single rows affected. When most of the rows in a page is locked by the query it might decide that escalating the lock into locking the entire page would be better, which may have the side effect of locking some rows not otherwise affected by the query.

If a select query and an update query are trying to escalate locks on the same table, they may cause a deadlock eventhough only a single table is involved.

Guffa
With MySQL the locking vary *a lot* between engines. Only InnoDB has row level locking, ISAM/MyISAM/Memory all lock the entire table for any update: http://dev.mysql.com/doc/refman/5.1/en/internal-locking.html
Remus Rusanu
I've just asked if InnoDb can use lock escalation on mysql forum. Let's see.
nightcoder