[ 
https://issues.apache.org/jira/browse/DERBY-3172?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12541091
 ] 

Mamta A. Satoor commented on DERBY-3172:
----------------------------------------

While working on this issue, I found that when a JCBC Connection is already 
closed and user attempts to close it again, in embedded mode, the driver simply 
returns from the method **without** sending a notification to the 
ConnectionEventListener. Following is the code for close() in 
iapi.jdbc.BrokeredConnection
public final void close() throws SQLException 
{ 
        if (isClosed)
                return;
        try {
                if (!control.closingConnection()) {
                        isClosed = true;
                        return;
                }
                isClosed = true;

                getRealConnection().close();
        } catch (SQLException sqle) {
                notifyException(sqle);
                throw sqle;
        }
}

But in the client driver side, if a Connection object is already closed, then 
next attempt to close it send connectionErrorOccurred to the listeners.  
Following is the code for close() in client.am.LogicalConnection
    synchronized public void close() throws SQLException {
        try
        {
            // we also need to loop thru all the logicalStatements and close 
them
            if (physicalConnection_ == null) {
                return;
            }
            if (physicalConnection_.agent_.loggingEnabled()) {
                physicalConnection_.agent_.logWriter_.traceEntry(this, "close");
            }

            if (physicalConnection_.isClosed()) // connection is closed or has 
become stale
            {
                pooledConnection_.trashConnection(new SqlException(null, 
                    new ClientMessageId(
                        SQLState.PHYSICAL_CONNECTION_ALREADY_CLOSED)));
            } else {
                physicalConnection_.closeForReuse();
                if (!physicalConnection_.isGlobalPending_()) {
                    pooledConnection_.recycleConnection();
                }
            }
            physicalConnection_ = null;
            pooledConnection_.nullLogicalConnection();
        }
        catch ( SqlException se )
        {
            throw se.getSQLException();
        }
    }


I am not sure why we have this difference in behavior between the 2 drivers. I 
will make the client driver match the behavior of embedded driver ie do not 
send any events if close is being called on a closed Connection object. Please 
let me know if anyone has objections to this.

> ConnectionEventListener.connectionErrorOccurred not being executed when 
> SQLState 08006 Error is thrown
> ------------------------------------------------------------------------------------------------------
>
>                 Key: DERBY-3172
>                 URL: https://issues.apache.org/jira/browse/DERBY-3172
>             Project: Derby
>          Issue Type: Bug
>          Components: JDBC
>    Affects Versions: 10.3.1.4
>            Reporter: Stan Bradbury
>            Assignee: Mamta A. Satoor
>         Attachments: DerbyNotification2.java
>
>
> The attached program demonstrates the problem.  Using the 
> ClientConnectionPoolDataSource40 with a connectionEventListener the defined 
> method connectionErrorOccurred is not executed after the Network Server is 
> shutdown and activity is performed on a previously established pooled 
> connection.
> Program also demonstrates that the connectionClosed method is executed when 
> the connection is closed.
> To run the reproduction:
> 1) start network server (listening on default host/port and  
> -noSecurityManager specified)
> 2) run the program
> Output is:
>  > java DerbyNotification2
> 10.3.1.5 - (579866)
> Apache Derby
>  .got connection...check if connectionClosed method is called
> EVENT CALLED: Connection closed happened
>  . . .
>  . . .Get connection and issue test SQL statement
>  . . .AS EXPECTED: no table exists
>  . SHUTDOWN Network server and check if connectionErrorOccurred is called
> now try to use the connection after the NS is STOPPED
> SQLState is: 08006
> Error is: -4499
> Message is: Insufficient data while reading from the network - expected a 
> minimum of 6 bytes and received only -1 bytes.  The connection has been 
> terminated.
> Exception in thread "main" java.sql.SQLNonTransientConnectionException: 
> Insufficient data while reading from the network - expected a minimum of 6 
> bytes and received only -1 bytes.  The connection has
>  been terminated.
>         at 
> org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Unknown 
> Source)
>         at org.apache.derby.client.am.SqlException.getSQLException(Unknown 
> Source)
>         at org.apache.derby.client.am.Connection.prepareStatement(Unknown 
> Source)
>         at 
> org.apache.derby.client.am.LogicalConnection.prepareStatement(Unknown Source)
>         at DerbyNotification2.runTest(DerbyNotification2.java:64)
>         at DerbyNotification2.main(DerbyNotification2.java:87)
> Caused by: org.apache.derby.client.am.DisconnectException: Insufficient data 
> while reading from the network - expected a minimum of 6 bytes and received 
> only -1 bytes.  The connection has been termina
> ted.
>         at org.apache.derby.client.net.Reply.fill(Unknown Source)
>         at org.apache.derby.client.net.Reply.ensureALayerDataInBuffer(Unknown 
> Source)
>         at org.apache.derby.client.net.Reply.readDssHeader(Unknown Source)
>         at org.apache.derby.client.net.Reply.startSameIdChainParse(Unknown 
> Source)
>         at 
> org.apache.derby.client.net.NetStatementReply.readPrepareDescribeOutput(Unknown
>  Source)
>         at 
> org.apache.derby.client.net.StatementReply.readPrepareDescribeOutput(Unknown 
> Source)
>         at 
> org.apache.derby.client.net.NetStatement.readPrepareDescribeOutput_(Unknown 
> Source)
>         at 
> org.apache.derby.client.am.Statement.readPrepareDescribeOutput(Unknown Source)
>         at 
> org.apache.derby.client.am.PreparedStatement.readPrepareDescribeInputOutput(Unknown
>  Source)
>         at 
> org.apache.derby.client.am.PreparedStatement.flowPrepareDescribeInputOutput(Unknown
>  Source)
>         at org.apache.derby.client.am.PreparedStatement.prepare(Unknown 
> Source)
>         at org.apache.derby.client.am.Connection.prepareStatementX(Unknown 
> Source)
>         ... 4 more

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to