You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-dev@db.apache.org by "Mamta A. Satoor (JIRA)" <ji...@apache.org> on 2007/11/07 20:50:51 UTC

[jira] Commented: (DERBY-3172) ConnectionEventListener.connectionErrorOccurred not being executed when SQLState 08006 Error is thrown

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

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

I investigated this Jira issue and following is what I found along with a proposed solution at the end.

Consider following piece of code In embedded mode, 
      EmbeddedConnectionPoolDataSource ds =
         new EmbeddedConnectionPoolDataSource();
      ((EmbeddedConnectionPoolDataSource)ds).setDatabaseName("c:/dellater/derby_3172_embedded;create=true");

        PooledConnection pooledCon = ds.getPooledConnection();
        pooledCon.addConnectionEventListener(this);
        Connection conn = pooledCon.getConnection();

        try
        {
                Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); 
                String url = "jdbc:derby:c:/dellater/derby_3172_embedded;shutdown=true";
                Connection c = DriverManager.getConnection(url);        		
        }
        catch (Exception e)
        {
               System.out.println("Exception shutting down Network Server");
        }

The shutdown above throws"Database 'c:/dellater/derby_3172_embedded' shutdown." exception but the connection event listener does not get any events at this point. Continuing the eg above with following 
        PrepareStatement ps1 = conn.prepareStatement("CREATE TABLE TAB1(COL1 INT NOT NULL)");
The above statement throws an exception(SQLState 08003 No current connection.). But before throwing the exception, the connection event listener gets an event about connection error. This part is missing when similar code is tried in Network Server.

Consider similar eg for Network Server code
        ClientConnectionPoolDataSource ds =
             new ClientConnectionPoolDataSource();
         ((ClientConnectionPoolDataSource)ds).setDatabaseName("c:/dellater/derby_3172_embedded;create=true");

        PooledConnection pooledCon = ds.getPooledConnection();
        pooledCon.addConnectionEventListener(this);
        Connection conn = pooledCon.getConnection();

        NetworkServerControl server = new NetworkServerControl();
        server.shutdown();        		
        PrepareStatement ps1 = conn.prepareStatement("CREATE TABLE TAB1(COL1 INT NOT NULL)");
When the code above is run in Network Server mode, shutdown of Network Server does not throw any exception to the client. But when the program gets to conn.prepareStatement, following exception(SQLState 08006) is thrown as expected
	A communications error has been detected: Software caused connection abort: recv failed.
*****But no connection event error is received by the connection event listener. *****

The difference in code that I find between client driver and embedded driver is following
iapi.jdbc.BrokeredConnection in embedded catches the exception about no current connection and notifies the listeners as follows
	public final PreparedStatement prepareStatement(String sql)
	    throws SQLException 
	{
		try {
			return control.wrapStatement(getRealConnection().prepareStatement(sql), sql, null);
		} catch (SQLException sqle) {
			notifyException(sqle);
			throw sqle;
		}
	}

But on the client side in client.am.LogicalConnection has following code (ie it does not do anything with SQLException that it receives)
    synchronized public java.sql.PreparedStatement prepareStatement(String sql) throws SQLException {
        checkForNullPhysicalConnection();
        return physicalConnection_.prepareStatement(sql);
    }

I think to solve the problem, we need to have try catch in prepareStatement method on the client side and send event to the listeners through pooledConnection_. We do something similar in close() method on the client side. I think this needs to be done for all JDBC methods implemented in client.am.LogicalConnection. Let me know if anyone has any thoughts on this approach. I will start looking at implementing this soon.

> 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.