postgresql-jdbc.git / summary / log / commit / refs

commit    1080bfefcbd5fe5bbff39781dec1ea807ae07386
Author:   Kris Jurka <books@ejurka.com>
Date:     Tue Apr 01 07:19:21 2008 +0000

    Fix a deadlock that occurs when retrieving notifications.  Normal
    query execution enters the QueryExecutor monitor and then calls a
    synchronized method in the ProtocolConnection to update the
    transaction state.  Notification retrieval operates in the reverse
    order, entering the ProtocolConnection monitor and then calling a
    synchronized method in the QueryExecutor.
    
    Remove the QueryExecutor call from ProtocolConnection and make the
    higher level code responsible for calling it so we always acquire
    locks in the same order.
    
    Report and diagnosis by Joao Rui Leal.


org/postgresql/core/QueryExecutor.java | 11 ++++++++++- org/postgresql/core/v2/ProtocolConnectionImpl.java | 3 +-- org/postgresql/core/v3/ProtocolConnectionImpl.java | 3 +-- org/postgresql/jdbc2/AbstractJdbc2Connection.java | 3 ++- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/org/postgresql/core/QueryExecutor.java b/org/postgresql/core/QueryExecutor.java index b0aea2c8..05c5f1b8 100644 --- a/org/postgresql/core/QueryExecutor.java +++ b/org/postgresql/core/QueryExecutor.java @@ -4,7 +4,7 @@ * Copyright (c) 2004, Open Cloud Limited. * * IDENTIFICATION -* $PostgreSQL: pgjdbc/org/postgresql/core/QueryExecutor.java,v 1.40 2005/02/01 07:27:53 jurka Exp $ +* $PostgreSQL: pgjdbc/org/postgresql/core/QueryExecutor.java,v 1.41 2008/01/08 06:56:27 jurka Exp $ * *------------------------------------------------------------------------- */ @@ -170,6 +170,15 @@ public interface QueryExecutor { */ Query createParameterizedQuery(String sql); // Parsed for parameter placeholders ('?') + /** + * Prior to attempting to retrieve notifications, we need to pull + * any recently received notifications off of the network buffers. + * The notification retrieval in ProtocolConnection cannot do this + * as it is prone to deadlock, so the higher level caller must be + * responsible which requires exposing this method. + */ + void processNotifies() throws SQLException; + // // Fastpath interface. // diff --git a/org/postgresql/core/v2/ProtocolConnectionImpl.java b/org/postgresql/core/v2/ProtocolConnectionImpl.java index 25024018..17766594 100644 --- a/org/postgresql/core/v2/ProtocolConnectionImpl.java +++ b/org/postgresql/core/v2/ProtocolConnectionImpl.java @@ -4,7 +4,7 @@ * Copyright (c) 2004, Open Cloud Limited. * * IDENTIFICATION -* $PostgreSQL: pgjdbc/org/postgresql/core/v2/ProtocolConnectionImpl.java,v 1.10 2006/12/01 08:53:45 jurka Exp $ +* $PostgreSQL: pgjdbc/org/postgresql/core/v2/ProtocolConnectionImpl.java,v 1.11 2008/01/08 06:56:27 jurka Exp $ * *------------------------------------------------------------------------- */ @@ -62,7 +62,6 @@ class ProtocolConnectionImpl implements ProtocolConnection { } public synchronized PGNotification[] getNotifications() throws SQLException { - executor.processNotifies(); PGNotification[] array = (PGNotification[])notifications.toArray(new PGNotification[notifications.size()]); notifications.clear(); return array; diff --git a/org/postgresql/core/v3/ProtocolConnectionImpl.java b/org/postgresql/core/v3/ProtocolConnectionImpl.java index 35e68521..4fbef086 100644 --- a/org/postgresql/core/v3/ProtocolConnectionImpl.java +++ b/org/postgresql/core/v3/ProtocolConnectionImpl.java @@ -4,7 +4,7 @@ * Copyright (c) 2004, Open Cloud Limited. * * IDENTIFICATION -* $PostgreSQL: pgjdbc/org/postgresql/core/v3/ProtocolConnectionImpl.java,v 1.11 2006/12/01 08:53:45 jurka Exp $ +* $PostgreSQL: pgjdbc/org/postgresql/core/v3/ProtocolConnectionImpl.java,v 1.12 2008/01/08 06:56:27 jurka Exp $ * *------------------------------------------------------------------------- */ @@ -65,7 +65,6 @@ class ProtocolConnectionImpl implements ProtocolConnection { } public synchronized PGNotification[] getNotifications() throws SQLException { - executor.processNotifies(); PGNotification[] array = (PGNotification[])notifications.toArray(new PGNotification[notifications.size()]); notifications.clear(); return array; diff --git a/org/postgresql/jdbc2/AbstractJdbc2Connection.java b/org/postgresql/jdbc2/AbstractJdbc2Connection.java index 1005de67..f6599eda 100644 --- a/org/postgresql/jdbc2/AbstractJdbc2Connection.java +++ b/org/postgresql/jdbc2/AbstractJdbc2Connection.java @@ -3,7 +3,7 @@ * Copyright (c) 2004-2008, PostgreSQL Global Development Group * * IDENTIFICATION -* $PostgreSQL: pgjdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java,v 1.47 2008/01/08 06:56:28 jurka Exp $ +* $PostgreSQL: pgjdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java,v 1.48 2008/02/19 06:12:24 jurka Exp $ * *------------------------------------------------------------------------- */ @@ -1022,6 +1022,7 @@ public abstract class AbstractJdbc2Connection implements BaseConnection public PGNotification[] getNotifications() throws SQLException { + getQueryExecutor().processNotifies(); // Backwards-compatibility hand-holding. PGNotification[] notifications = protoConnection.getNotifications(); return (notifications.length == 0 ? null : notifications); [parent: 43e4484d129d]