Thread: Deadlock problem

Deadlock problem

From
"Vit Timchishin"
Date:
Hello.

I have an multithreaded java application using postgresql. I am using UR mode (handling locking internally)
and wa shoping to have no problems with locks.
But now I have locking porlbme where there is only one thread calling posgresql and locking in wait.
Looking at pg_lock I can see a lot of locks each holding exclusive a transaction (other two fields are empty).
And for one transaction there is one PID holding Exclusive Lock and another waiting for shared lock for
same transaction.
I suppose that this means that I've first used connection object from one thread and this thread pid (linux
x86-64) took exclusive lock and now another thread tries to use same connection and is going into lock.
Am I correct? If so, why this exclusive locks are help while there no other queries executed? Or does this
mean I can't use same connection object from different threads?


С уважением,
Виталий Валериевич Тимчишин,
Технический Директор
ООО "Голден Технолоджис"
http://www.gtech-ua.com




Re: Deadlock problem

From
Kris Jurka
Date:

On Fri, 18 Nov 2005, Vit Timchishin wrote:

> I have an multithreaded java application using postgresql. I am using UR
> mode (handling locking internally) and wa shoping to have no problems
> with locks. But now I have locking porlbme where there is only one
> thread calling posgresql and locking in wait. Looking at pg_lock I can
> see a lot of locks each holding exclusive a transaction (other two
> fields are empty). And for one transaction there is one PID holding
> Exclusive Lock and another waiting for shared lock for same transaction.
> I suppose that this means that I've first used connection object from
> one thread and this thread pid (linux x86-64) took exclusive lock and
> now another thread tries to use same connection and is going into lock.
> Am I correct? If so, why this exclusive locks are help while there no
> other queries executed? Or does this mean I can't use same connection
> object from different threads?

I'm a little bit unclear on how you are using connections.  Does your
application have only one Connection object that it shares among various
threads?  If this is the case the postgresql jdbc driver will block a
thread when another thread is executing a statement from the same
connection.  The server does not support multiplexing queries so the
driver can only allow one to execute at any given time.  If this is the
case you may want to open more than one Connection in your application.
This situation cannot cause a block on the server side because a
Connection cannot block itself.  If you are blocked on the server side
(with only one Connection) then you must be waiting for another
connection's resources, perhaps from another application or maintenence
command.

Kris Jurka


Re: Deadlock problem

From
Andrew Sullivan
Date:
On Fri, Nov 18, 2005 at 12:09:16PM +0200, Vit Timchishin wrote:

> I suppose that this means that I've first used connection object
> from one thread and this thread pid (linux x86-64) took exclusive
> lock and now another thread tries to use same connection and is
> going into lock. Am I correct? If so, why this exclusive locks are
> help while there no other queries executed? Or does this mean I
> can't use same connection object from different threads?

The answer to question (1) is "presumably", and the answer to
question (2) is "there is too another query being executed".  There
_must_ be a query being executed by the back end (whatever your
application thinks), because that's what's got the exlusive lock.
Moreover, an exclusive lock is pretty strong -- presumably a row is
being modified.  But I suspect that, whatever you're doing, you don't
really want to be using the same connection object from different
threads (unless you mean, serially -- like a connection pool which
hands out "the same connection" multiple times).  If this connection
is being actively used by more than one thread concurrently, things
are going to break in really surprising ways.

A
--
Andrew Sullivan  | ajs@crankycanuck.ca
"The year's penultimate month" is not in truth a good way of saying
November.
        --H.W. Fowler

Re: Deadlock problem

From
Kris Jurka
Date:

On Fri, 18 Nov 2005, Andrew Sullivan wrote:

> If this connection is being actively used by more than one thread
> concurrently, things are going to break in really surprising ways.
>

The JDBC driver is threadsafe so multiple threads may make calls
simultaneously, but internally only one is executed at a time.  Clearly
running with autocommit = false requires some coordination of
transactions, but multiple threads are not in and of themselves dangerous.

Kris Jurka


Re: Deadlock problem

From
Andrew Sullivan
Date:
On Fri, Nov 18, 2005 at 02:49:53PM -0500, Kris Jurka wrote:
> simultaneously, but internally only one is executed at a time.  Clearly
> running with autocommit = false requires some coordination of
> transactions, but multiple threads are not in and of themselves dangerous.

I'd _really_ like to see an example of an application that did this
correctly and without any bugs.  I've seen people do it, yes; but I
haven't seen it working without fairly serious problems.  (Besides,
isn't solving this sort of pain what a pool is for?  Why reinvent the
wheel, and make it square to boot?)

A

--
Andrew Sullivan  | ajs@crankycanuck.ca
When my information changes, I alter my conclusions.  What do you do sir?
        --attr. John Maynard Keynes

Re: Deadlock problem

From
Andres Olarte
Date:
There's also the option of using a queue that's accessed by various threads and a single thread with a single connection that actually talks with the DB. I've been sucessfull with this aproach, at least in a very particular and well defined scenario. As for reiventing the wheel, it's probably very pointless and prone to erros like Andrew mentions.  The DB has transactions, they work well, use them to your advantage.

Andres

Re: Deadlock problem

From
"Vit Timchishin"
Date:
On Fri, 18 Nov 2005 13:31:23 -0500 (EST), Kris Jurka wrote:

>
>
>On Fri, 18 Nov 2005, Vit Timchishin wrote:
>
>> I have an multithreaded java application using postgresql. I am using UR
>> mode (handling locking internally) and wa shoping to have no problems
>> with locks. But now I have locking porlbme where there is only one
>> thread calling posgresql and locking in wait. Looking at pg_lock I can
>> see a lot of locks each holding exclusive a transaction (other two
>> fields are empty). And for one transaction there is one PID holding
>> Exclusive Lock and another waiting for shared lock for same transaction.
>> I suppose that this means that I've first used connection object from
>> one thread and this thread pid (linux x86-64) took exclusive lock and
>> now another thread tries to use same connection and is going into lock.
>> Am I correct? If so, why this exclusive locks are help while there no
>> other queries executed? Or does this mean I can't use same connection
>> object from different threads?
>
>I'm a little bit unclear on how you are using connections.  Does your
>application have only one Connection object that it shares among various
>threads?  If this is the case the postgresql jdbc driver will block a
>thread when another thread is executing a statement from the same
>connection.  The server does not support multiplexing queries so the
>driver can only allow one to execute at any given time.  If this is the
>case you may want to open more than one Connection in your application.
>This situation cannot cause a block on the server side because a
>Connection cannot block itself.  If you are blocked on the server side
>(with only one Connection) then you must be waiting for another
>connection's resources, perhaps from another application or maintenence
>command.

I am not using one connection and at the time of block there is only one active query (that is locked) at the
whole database (in my test case). But for one transaction it may be used by different java threads (e.g. main
thread and finalizer) and it seems that this is producing problems because exclusive lock is held after
statement have finished. It is possible that I am still having open resultsets (did not check), but they are all
forward only and not updateable.

С уважением,
Виталий Валериевич Тимчишин,
Технический Директор
ООО "Голден Технолоджис"
http://www.gtech-ua.com




Re: Deadlock problem

From
Kris Jurka
Date:

On Mon, 21 Nov 2005, Vit Timchishin wrote:

> I am not using one connection and at the time of block there is only one
> active query (that is locked) at the whole database (in my test case).
> But for one transaction it may be used by different java threads (e.g.
> main thread and finalizer) and it seems that this is producing problems
> because exclusive lock is held after statement have finished. It is
> possible that I am still having open resultsets (did not check), but
> they are all forward only and not updateable.
>

Locks are always held until transaction commit, not the end of an
individual statement.  So, while you may only have one statement executing
you have more than one transaction in progress and this is causing your
deadlocks.  Consider a table with a primary key:

CREATE TABLE t(a int primary key);

Connection 1:
BEGIN;
INSERT INTO t VALUES (1);

Connection 2:
BEGIN;
INSERT INTO t VALUES (1);

Connection 2 must wait for connection 1 to either commit or rollback
before it knows whether it can legally insert its value.  This is true
even if connection 1 performed its insert a week ago, the transaction is
still in doubt even if the statement has completed running.

Kris Jurka

Re: Deadlock problem

From
"Vit Timchishin"
Date:
On Mon, 21 Nov 2005 18:06:37 -0500 (EST), Kris Jurka wrote:

>
>
>On Mon, 21 Nov 2005, Vit Timchishin wrote:
>
>> I am not using one connection and at the time of block there is only one
>> active query (that is locked) at the whole database (in my test case).
>> But for one transaction it may be used by different java threads (e.g.
>> main thread and finalizer) and it seems that this is producing problems
>> because exclusive lock is held after statement have finished. It is
>> possible that I am still having open resultsets (did not check), but
>> they are all forward only and not updateable.
>>
>
>Locks are always held until transaction commit, not the end of an
>individual statement.  So, while you may only have one statement executing
>you have more than one transaction in progress and this is causing your
>deadlocks.

This is not the problem. I know good about locks, but this one:
 relation | database | transaction |  pid  |      mode       | granted
----------+----------+-------------+-------+-----------------+---------
          |          |     1109601 | 32172 | ExclusiveLock   | t

1) Not related to any relation. Relation and database fields are null
2) Intertransaction - transaction field of lock that is granted (example above) and that is trying to lock are
equal. The only difference is the pid column (and that the lock that is trying is SharedLock and granted = f).


С уважением,
Виталий Валериевич Тимчишин,
Технический Директор
ООО "Голден Технолоджис"
http://www.gtech-ua.com