Derby
  1. Derby
  2. DERBY-941

Add JDBC4 support for Statement Events

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 10.0.2.0
    • Fix Version/s: 10.2.1.6
    • Component/s: JDBC
    • Labels:
      None

      Description

      As described in the JDBC 4 spec, sections 11.2, 11.7, and 3.1.

      These are the methods which let app servers listen for connection and statement closure and invalidation events.

      Section 11.2 of the JDBC 4 spec explains connection events: Connection pool managers which implement the ConnectionEventListener interface can register themselves to listen for "connectionClosed" and fatal "connectionErrorOccurred" events. App servers can use these events to help them manage the recycling of connections back to the connection pool.

      Section 11.7 of the JDBC 4 spec explains statement events: Statement pools which implement StatementEventListener can register themselves to listen for "statementClosed" and "statementErrorOccurred" events. Again, this helps statement pools manage the recycling of statements back to the pool.

      1. statementeventlisteners_client_v4.stat
        1 kB
        V.Narayanan
      2. statementeventlisteners_client_v4.diff
        73 kB
        V.Narayanan
      3. diff_between_ver2_ver3.txt
        0.3 kB
        V.Narayanan
      4. statementeventlisteners_client_v3.diff
        72 kB
        V.Narayanan
      5. statementeventlisteners_client_v3.stat
        1 kB
        V.Narayanan
      6. statementeventlisteners_client_v2.diff
        72 kB
        V.Narayanan
      7. statementeventlisteners_client_v2.stat
        1 kB
        V.Narayanan
      8. statementeventlisteners_client_v1.diff
        74 kB
        V.Narayanan
      9. statementeventlisteners_client_v1.stat
        1 kB
        V.Narayanan
      10. statementeventlisteners_client.diff
        62 kB
        V.Narayanan
      11. statementeventlisteners_client.html
        7 kB
        V.Narayanan
      12. statementeventlisteners_client.stat
        1 kB
        V.Narayanan
      13. statementeventlisteners_embedded_v3.diff
        15 kB
        V.Narayanan
      14. statementeventlisteners_embedded_v3.stat
        0.5 kB
        V.Narayanan
      15. ListenerTest.java
        3 kB
        Knut Anders Hatlen
      16. statementeventlisteners_embedded_v2.diff
        25 kB
        V.Narayanan
      17. statementeventlisteners_embedded_v2.stat
        0.9 kB
        V.Narayanan
      18. statementeventlisteners_embedded.diff
        26 kB
        V.Narayanan
      19. statementeventlisteners_embedded.stat
        0.9 kB
        V.Narayanan
      20. statementeventlisteners_embedded_ver1.html
        11 kB
        V.Narayanan

        Activity

        Hide
        Rick Hillegas added a comment -

        Concerning connection events, here is Section 11.2 of the JDBC 4 spec:

        70 JDBC 4.0 Specification ? October 2005
        11.2 Connection Events
        Recall that when an application calls the method Connection.close, the
        underlying physical connection?the PooledConnection object?is available for
        reuse. JavaBeans-style events are used to notify the connection pool manager (the
        application server) that a PooledConnection object can be recycled.
        In order to be notified of an event on a PooledConnection object, the connection
        pool manager must implement the ConnectionEventListener interface and then
        be registered as a listener by that PooledConnection object. The
        ConnectionEventListener interface defines the following two methods, which
        correspond to the two kinds of events that can occur on a PooledConnection
        object:
        ? connectionClosed ? triggered when the logical Connection object associated
        with this PooledConnection object is closed, that is, the application called the
        method Connection.close
        ? connectionErrorOccurred ? triggered when a fatal error, such as the server
        crashing, causes the connection to be lost
        A connection pool manager registers itself as a listener for a PooledConnection
        object using the PooledConnection.addConnectionEventListener method.
        Typically, a connection pool manager registers itself as a
        ConnectionEventListener before returning a Connection object to an
        application.
        The driver invokes the ConnectionEventListener methods
        connectionClosed and connectionErrorOccurred when the corresponding
        events occur. Both methods take a ConnectionEvent object as a parameter, which
        can be used to determine which PooledConnection object was closed or had an
        error. When the JDBC application closes its logical connection, the JDBC driver
        notifies the connection pool manager (the listener) by calling the listener's
        implementation of the method connectionClosed. At this point, the connection
        pool manager can return the PooledConnection object to the pool for reuse.
        When an error occurs, the JDBC driver notifies the listener by calling its
        connectionErrorOccurred method and then throws an SQLException object to
        the application to notify it of the same error. In the event of a fatal error, the bad
        PooledConnection object is not returned to the pool. Instead, the connection pool
        manager calls the PooledConnection.close method on the PooledConnection
        object to close the physical connection.

        Concerning statement events, here is section 11.7 of the JDBC4 spec:

        11.7 Statement Events
        If the connection pool manager supports Statement pooling for
        PreparedStatement objects, it must implement the StatementEventListener
        interface and then be registered as a listener by that PooledConnection object. The
        StatementEventListener interface defines the following two methods, which
        correspond to the two kinds of events that can occur on a PreparedStatement
        object:
        ? statementClosed ? triggered when the logical PreparedStatement object
        associated with this PooledConnection object is closed, that is, the application
        called the method PreparedStatement.close
        ? statementErrorOccurred ? triggered when a JDBC driver determines that a
        PreparedStatement object is no longer valid
        A connection pool manager registers itself as a listener for a PreparedStatement
        object using the PooledConnection.addStatementEventListener method.
        Typically, a connection pool manager registers itself as a
        StatementEventListener before returning a PreparedStatement object to an
        application.
        The driver invokes the StatementEventListener methods statementClosed
        and statementErrorOccurred when the corresponding events occur. Both
        methods take a statementEvent object as a parameter, which can be used to
        determine which PreparedStatement object was closed or had an error. When the
        JDBC application closes its logical prepared statement, the JDBC driver notifies the
        connection pool manager (the listener) by calling the listener's implementation of the
        method statementClosed. At this point, the connection pool manager can return
        the PreparedStatement object to the pool for reuse.
        When an error occurs that makes a PreparedStatement object invalid, the JDBC
        driver notifies the listener by calling its statementErrorOccurred method and
        then throws an SQLException object to the application to notify it of the same error.

        Show
        Rick Hillegas added a comment - Concerning connection events, here is Section 11.2 of the JDBC 4 spec: 70 JDBC 4.0 Specification ? October 2005 11.2 Connection Events Recall that when an application calls the method Connection.close, the underlying physical connection?the PooledConnection object?is available for reuse. JavaBeans-style events are used to notify the connection pool manager (the application server) that a PooledConnection object can be recycled. In order to be notified of an event on a PooledConnection object, the connection pool manager must implement the ConnectionEventListener interface and then be registered as a listener by that PooledConnection object. The ConnectionEventListener interface defines the following two methods, which correspond to the two kinds of events that can occur on a PooledConnection object: ? connectionClosed ? triggered when the logical Connection object associated with this PooledConnection object is closed, that is, the application called the method Connection.close ? connectionErrorOccurred ? triggered when a fatal error, such as the server crashing, causes the connection to be lost A connection pool manager registers itself as a listener for a PooledConnection object using the PooledConnection.addConnectionEventListener method. Typically, a connection pool manager registers itself as a ConnectionEventListener before returning a Connection object to an application. The driver invokes the ConnectionEventListener methods connectionClosed and connectionErrorOccurred when the corresponding events occur. Both methods take a ConnectionEvent object as a parameter, which can be used to determine which PooledConnection object was closed or had an error. When the JDBC application closes its logical connection, the JDBC driver notifies the connection pool manager (the listener) by calling the listener's implementation of the method connectionClosed. At this point, the connection pool manager can return the PooledConnection object to the pool for reuse. When an error occurs, the JDBC driver notifies the listener by calling its connectionErrorOccurred method and then throws an SQLException object to the application to notify it of the same error. In the event of a fatal error, the bad PooledConnection object is not returned to the pool. Instead, the connection pool manager calls the PooledConnection.close method on the PooledConnection object to close the physical connection. Concerning statement events, here is section 11.7 of the JDBC4 spec: 11.7 Statement Events If the connection pool manager supports Statement pooling for PreparedStatement objects, it must implement the StatementEventListener interface and then be registered as a listener by that PooledConnection object. The StatementEventListener interface defines the following two methods, which correspond to the two kinds of events that can occur on a PreparedStatement object: ? statementClosed ? triggered when the logical PreparedStatement object associated with this PooledConnection object is closed, that is, the application called the method PreparedStatement.close ? statementErrorOccurred ? triggered when a JDBC driver determines that a PreparedStatement object is no longer valid A connection pool manager registers itself as a listener for a PreparedStatement object using the PooledConnection.addStatementEventListener method. Typically, a connection pool manager registers itself as a StatementEventListener before returning a PreparedStatement object to an application. The driver invokes the StatementEventListener methods statementClosed and statementErrorOccurred when the corresponding events occur. Both methods take a statementEvent object as a parameter, which can be used to determine which PreparedStatement object was closed or had an error. When the JDBC application closes its logical prepared statement, the JDBC driver notifies the connection pool manager (the listener) by calling the listener's implementation of the method statementClosed. At this point, the connection pool manager can return the PreparedStatement object to the pool for reuse. When an error occurs that makes a PreparedStatement object invalid, the JDBC driver notifies the listener by calling its statementErrorOccurred method and then throws an SQLException object to the application to notify it of the same error.
        Hide
        V.Narayanan added a comment -

        This patch is not intended for submission but is a request for comments on the work done so far in this area on the embedded side

        Show
        V.Narayanan added a comment - This patch is not intended for submission but is a request for comments on the work done so far in this area on the embedded side
        Hide
        V.Narayanan added a comment -

        please note that this patch has a dependency on derby-1137

        Show
        V.Narayanan added a comment - please note that this patch has a dependency on derby-1137
        Hide
        Rick Hillegas added a comment -

        Hi Narayanan,

        Thanks for the patch and the accompanying explanation page. One issue: EmbeddedConnectionPoolDataSource40 needs javadoc.

        Show
        Rick Hillegas added a comment - Hi Narayanan, Thanks for the patch and the accompanying explanation page. One issue: EmbeddedConnectionPoolDataSource40 needs javadoc.
        Hide
        V.Narayanan added a comment -

        Hi Rick,
        Thank you for going through the patch. The class EmbeddedConnectionPoolDataSource40 is being added as part of derby-1137. I wanted to use the method getPooledConnection() method in EmbedConnectionPoolDataSource40 which will override the existing method in EmbedConnectionPoolDataSource to return a PooledConnection40 object. Since the refractoring of these classes were going on I added a implementation to my patch to basically demonstrate how the patch will look like once 1137 is through.

        please note that this patch has been added to get comments on my solution and to ensure that I am progressing in the right direction as far my solution is concerned. This patch is not ready for commit as yet

        Narayanan

        Show
        V.Narayanan added a comment - Hi Rick, Thank you for going through the patch. The class EmbeddedConnectionPoolDataSource40 is being added as part of derby-1137. I wanted to use the method getPooledConnection() method in EmbedConnectionPoolDataSource40 which will override the existing method in EmbedConnectionPoolDataSource to return a PooledConnection40 object. Since the refractoring of these classes were going on I added a implementation to my patch to basically demonstrate how the patch will look like once 1137 is through. please note that this patch has been added to get comments on my solution and to ensure that I am progressing in the right direction as far my solution is concerned. This patch is not ready for commit as yet Narayanan
        Hide
        Rick Hillegas added a comment -

        Hi Narayanan: Now that DERBY-1163 and DERBY-1137 are committed, is this patch ready for committing? Thanks-Rick

        Show
        Rick Hillegas added a comment - Hi Narayanan: Now that DERBY-1163 and DERBY-1137 are committed, is this patch ready for committing? Thanks-Rick
        Hide
        Rick Hillegas added a comment -

        Hi Narayanan,

        I'm afraid that I can't apply this patch. I think it might have been garbled when you uploaded it. Could you retry uploading it? Thanks-Rick

        Show
        Rick Hillegas added a comment - Hi Narayanan, I'm afraid that I can't apply this patch. I think it might have been garbled when you uploaded it. Could you retry uploading it? Thanks-Rick
        Hide
        V.Narayanan added a comment -

        Hi Rick,
        Thank you for the reviews of this patch. The class EmbeddedConnectionPoolDataSource40 ,which ,has been added as part of 1137 is also present in this patch which as indicated by a class level comment in this patch is a dummy implementation which was to be removed after the commit of 1137. I am on this one. I will do this re-submit the patch again
        thanx
        Narayanan

        Show
        V.Narayanan added a comment - Hi Rick, Thank you for the reviews of this patch. The class EmbeddedConnectionPoolDataSource40 ,which ,has been added as part of 1137 is also present in this patch which as indicated by a class level comment in this patch is a dummy implementation which was to be removed after the commit of 1137. I am on this one. I will do this re-submit the patch again thanx Narayanan
        Hide
        V.Narayanan added a comment -

        Primary change has been to the class org.apache.derbyTesting.functionTests.util.TestUtil

        The getConnectionPoolDataSource() method had to be changed to return either EmbedConnectionPoolDataSource or EmbedConnectionPoolDataSource40 depending
        on the jdk version under use.

        I have moved the code for determining whether we need to use a 40 class to the method checkForJDBC40Implementation this method returns a String representing the correct name of the class to be used.

        I have changed the constant UNABLE_TO_UNWRAP in SQLConstants.java to hold the value "XJ128" instead of the existing "XJ120" to allow the jdbc4 tests to run correctly. This is causing failures in the jdbc4 tests currently. Once
        this issue is fixed it can be removed from this patch also.

        thanx
        Narayanan

        Show
        V.Narayanan added a comment - Primary change has been to the class org.apache.derbyTesting.functionTests.util.TestUtil The getConnectionPoolDataSource() method had to be changed to return either EmbedConnectionPoolDataSource or EmbedConnectionPoolDataSource40 depending on the jdk version under use. I have moved the code for determining whether we need to use a 40 class to the method checkForJDBC40Implementation this method returns a String representing the correct name of the class to be used. I have changed the constant UNABLE_TO_UNWRAP in SQLConstants.java to hold the value "XJ128" instead of the existing "XJ120" to allow the jdbc4 tests to run correctly. This is causing failures in the jdbc4 tests currently. Once this issue is fixed it can be removed from this patch also. thanx Narayanan
        Hide
        Rick Hillegas added a comment -

        Committed statementeventlisteners_embedded_v2.diff at subversion revision 394788. Derbyall runs cleanly modulo the wisconsin diffs. The jdbc4 tests pass modulo the pre-existing problem in TestResultSetMethods.

        Show
        Rick Hillegas added a comment - Committed statementeventlisteners_embedded_v2.diff at subversion revision 394788. Derbyall runs cleanly modulo the wisconsin diffs. The jdbc4 tests pass modulo the pre-existing problem in TestResultSetMethods.
        Hide
        Knut Anders Hatlen added a comment -

        I have read what the spec says about statement event listeners, but it
        is still not quite clear to me how they are supposed to work.

        The javadoc for StatementEventListener.statementErrorOccurred() says:

        The driver calls this method on all StatementEventListeners
        registered on the connection when it detects that a
        PreparedStatement is invalid. The driver calls this method just
        before it throws the SQLException, contained in the given event, to
        the application.

        Does this mean that no more than one statementErrorOccurred event
        should be sent per PreparedStatement? I think so, since the statement
        becomes invalid once, right?

        I'm also not sure exactly how one determines that a statement is
        invalid. It seems like checkStatementValidity() considers a statement
        invalid when it sees an SQLSTATE in class 42 (syntax error or access
        rule violation).

        I wrote a test program (ListenerTest.java) which does the following:

        1. create table "mytable"
        2. prepare statement "select * from mytable"
        3. execute prepared statement
        4. drop table "mytable"
        5. execute prepared statement
        6. execute prepared statement
        7. recreate table "mytable"
        8. execute prepared statement
        9. close prepared statement

        I get an exception and an error-occurred event in step 5 and step 6,
        and a closed event in step 9.

        I'm not sure what I should expect, but what puzzles me is

        1) I get two error-occurred events on the same statement (that is,
        I'm told twice that the statement is invalid)

        2) Even though I'm told that the statement is invalid, I'm able to
        execute it successfully in step 8

        Show
        Knut Anders Hatlen added a comment - I have read what the spec says about statement event listeners, but it is still not quite clear to me how they are supposed to work. The javadoc for StatementEventListener.statementErrorOccurred() says: The driver calls this method on all StatementEventListeners registered on the connection when it detects that a PreparedStatement is invalid. The driver calls this method just before it throws the SQLException, contained in the given event, to the application. Does this mean that no more than one statementErrorOccurred event should be sent per PreparedStatement? I think so, since the statement becomes invalid once, right? I'm also not sure exactly how one determines that a statement is invalid. It seems like checkStatementValidity() considers a statement invalid when it sees an SQLSTATE in class 42 (syntax error or access rule violation). I wrote a test program (ListenerTest.java) which does the following: 1. create table "mytable" 2. prepare statement "select * from mytable" 3. execute prepared statement 4. drop table "mytable" 5. execute prepared statement 6. execute prepared statement 7. recreate table "mytable" 8. execute prepared statement 9. close prepared statement I get an exception and an error-occurred event in step 5 and step 6, and a closed event in step 9. I'm not sure what I should expect, but what puzzles me is 1) I get two error-occurred events on the same statement (that is, I'm told twice that the statement is invalid) 2) Even though I'm told that the statement is invalid, I'm able to execute it successfully in step 8
        Hide
        Anurag Shekhar added a comment -

        Statement Event Listener is expected to be used by Statement pooling.
        Nothing stops a regular application of add use this but section 11.7 hints about it. My understanding is that the statement pool will use this even to drop the statement from the pool and there won't be any question of the invalid statement being used again. In case it does most probably its a faulty implementation of pooling. The spec and api says the even should be raised when the driver detects the statment is invalid and before throwing the exception. I don't see why it can't be thrown twise.

        Your 2nd point its quite interresting doe that scenario ment the statement was never invalid ?

        Show
        Anurag Shekhar added a comment - Statement Event Listener is expected to be used by Statement pooling. Nothing stops a regular application of add use this but section 11.7 hints about it. My understanding is that the statement pool will use this even to drop the statement from the pool and there won't be any question of the invalid statement being used again. In case it does most probably its a faulty implementation of pooling. The spec and api says the even should be raised when the driver detects the statment is invalid and before throwing the exception. I don't see why it can't be thrown twise. Your 2nd point its quite interresting doe that scenario ment the statement was never invalid ?
        Hide
        Knut Anders Hatlen added a comment -

        Hi Anurag,

        I'm not sure if the statement was invalid. That, I guess, depends on
        the definition of invalid (you could perhaps say it was temporarily
        invalid). The javadoc for StatementEventListener refers to a similar
        situation:

        For some databases, a statement becomes invalid if a DDL operation
        is performed that affects the table. For example an application may
        create a temporary table to do some work on the table and then
        destroy it. It may later recreate the same table when it is needed
        again. Some databases will invalidate any prepared statements that
        reference the temporary table when the table is dropped.

        Since Derby allows you to use the same prepared statement after the
        table is recreated, I would say that the statement was not invalid,
        and that a statementErrorOccurred event should not be raised.

        Maybe prepared statements are invalidated only when the connection
        fails or the statement is closed?

        Show
        Knut Anders Hatlen added a comment - Hi Anurag, I'm not sure if the statement was invalid. That, I guess, depends on the definition of invalid (you could perhaps say it was temporarily invalid). The javadoc for StatementEventListener refers to a similar situation: For some databases, a statement becomes invalid if a DDL operation is performed that affects the table. For example an application may create a temporary table to do some work on the table and then destroy it. It may later recreate the same table when it is needed again. Some databases will invalidate any prepared statements that reference the temporary table when the table is dropped. Since Derby allows you to use the same prepared statement after the table is recreated, I would say that the statement was not invalid, and that a statementErrorOccurred event should not be raised. Maybe prepared statements are invalidated only when the connection fails or the statement is closed?
        Hide
        V.Narayanan added a comment -

        Hi,
        thanx for the comments!

        1) In the example we are waiting for the affect of the Delete table operation to be undone by the create operation before the PreparedStatement
        becomes usable again. Is'nt this a special case where the DDL undoes the operation of an earlier DDL? What if the create table did not happen at
        all? Then would'nt the PreparedStatement remain invalid?

        2) There are two cases for this Error Occurred Event as I see it

        a) Assume that the ConnectionPoolManager which has registered itself to listen to statement events is actually doing what is mentioned as part of
        the javadoc comment (i.e.) creating a temporary table in this case it can catch the error occurred event check the content to see the
        PreparedStatement and also the SQLException object contained within the StatementEvent (which would indicate the reason for occurrence
        of the event) and if it occurred because of non-existence of the temporary table ignore it.

        b) In the case that the ConnectionPoolManager has not created a temporary table and it is a genuine case of a invalid PreparedStatement it needs
        to know it can make use of the error occurred event that is raised.

        Thus throwing a error occurred event would allow the ConnectionPoolManager to decide what needs to happen

        Narayanan

        Show
        V.Narayanan added a comment - Hi, thanx for the comments! 1) In the example we are waiting for the affect of the Delete table operation to be undone by the create operation before the PreparedStatement becomes usable again. Is'nt this a special case where the DDL undoes the operation of an earlier DDL? What if the create table did not happen at all? Then would'nt the PreparedStatement remain invalid? 2) There are two cases for this Error Occurred Event as I see it a) Assume that the ConnectionPoolManager which has registered itself to listen to statement events is actually doing what is mentioned as part of the javadoc comment (i.e.) creating a temporary table in this case it can catch the error occurred event check the content to see the PreparedStatement and also the SQLException object contained within the StatementEvent (which would indicate the reason for occurrence of the event) and if it occurred because of non-existence of the temporary table ignore it. b) In the case that the ConnectionPoolManager has not created a temporary table and it is a genuine case of a invalid PreparedStatement it needs to know it can make use of the error occurred event that is raised. Thus throwing a error occurred event would allow the ConnectionPoolManager to decide what needs to happen Narayanan
        Hide
        V.Narayanan added a comment -

        Hi,
        We are throwing the error occurred event only upon doing an execute on the PreparedStatement. If the ConnectionPoolManager did know that the temporary table or the table used in the PreparedStatement or in the generalized case knew of a DDL invalidating a PreparedStatement why would it do a execute on the PreparedStatement? Does'nt this qualify as a faulty Pooling implementation? If it were using a temporary table it would do an execute only during the time that the temporary table exists.
        Narayanan

        Show
        V.Narayanan added a comment - Hi, We are throwing the error occurred event only upon doing an execute on the PreparedStatement. If the ConnectionPoolManager did know that the temporary table or the table used in the PreparedStatement or in the generalized case knew of a DDL invalidating a PreparedStatement why would it do a execute on the PreparedStatement? Does'nt this qualify as a faulty Pooling implementation? If it were using a temporary table it would do an execute only during the time that the temporary table exists. Narayanan
        Hide
        Knut Anders Hatlen added a comment -

        > V.Narayanan commented on DERBY-941:
        > -----------------------------------
        >
        > Hi,
        > thanx for the comments!
        >
        > 1) In the example we are waiting for the affect of the Delete table
        > operation to be undone by the create operation before the
        > PreparedStatement becomes usable again. Is'nt this a special case
        > where the DDL undoes the operation of an earlier DDL?

        Maybe. It's probably a special case that the table is dropped and the
        statement is re-executed too, but it's still a case...

        > What if the create table did not happen at all? Then would'nt the
        > PreparedStatement remain invalid?

        That depends on how "invalid" is defined, but the way I read the
        javadoc for StatementEventListener, it is seems like the spec
        considers the statement as valid, since it is not necessarily unusable
        in the future.

        > 2) There are two cases for this Error Occurred Event as I see it
        >
        > a) Assume that the ConnectionPoolManager which has registered
        > itself to listen to statement events is actually doing what is
        > mentioned as part of the javadoc comment (i.e.) creating a
        > temporary table in this case it can catch the error occurred
        > event check the content to see the PreparedStatement and also
        > the SQLException object contained within the StatementEvent
        > (which would indicate the reason for occurrence of the event)
        > and if it occurred because of non-existence of the temporary
        > table ignore it.

        In that case, the connection pool manager needs knowledge about how
        the tables are used and whether the database invalidates statements on
        DDL operations. I don't think we can expect the manager to have such
        knowledge.

        > b) In the case that the ConnectionPoolManager has not created
        > a temporary table and it is a genuine case of a invalid
        > PreparedStatement it needs to know it can make use of the
        > error occurred event that is raised.
        >
        > Thus throwing a error occurred event would allow the
        > ConnectionPoolManager to decide what needs to happen

        Again, I don't think the connection pool manager has enough
        information to decide this. It is the application that creates and
        accesses the table. The manager just does what the application tells
        it to do, and it has no way to find out whether the application will
        recreate the table later.

        > We are throwing the error occurred event only upon doing an execute
        > on the PreparedStatement. If the ConnectionPoolManager did know that
        > the temporary table or the table used in the PreparedStatement or in
        > the generalized case knew of a DDL invalidating a PreparedStatement
        > why would it do a execute on the PreparedStatement? Does'nt this
        > qualify as a faulty Pooling implementation? If it were using a
        > temporary table it would do an execute only during the time that the
        > temporary table exists. Narayanan

        No, I don't think this means the pool manager is faulty. It is the
        application, not the manager, that decides when it invokes execute().

        Show
        Knut Anders Hatlen added a comment - > V.Narayanan commented on DERBY-941 : > ----------------------------------- > > Hi, > thanx for the comments! > > 1) In the example we are waiting for the affect of the Delete table > operation to be undone by the create operation before the > PreparedStatement becomes usable again. Is'nt this a special case > where the DDL undoes the operation of an earlier DDL? Maybe. It's probably a special case that the table is dropped and the statement is re-executed too, but it's still a case... > What if the create table did not happen at all? Then would'nt the > PreparedStatement remain invalid? That depends on how "invalid" is defined, but the way I read the javadoc for StatementEventListener, it is seems like the spec considers the statement as valid, since it is not necessarily unusable in the future. > 2) There are two cases for this Error Occurred Event as I see it > > a) Assume that the ConnectionPoolManager which has registered > itself to listen to statement events is actually doing what is > mentioned as part of the javadoc comment (i.e.) creating a > temporary table in this case it can catch the error occurred > event check the content to see the PreparedStatement and also > the SQLException object contained within the StatementEvent > (which would indicate the reason for occurrence of the event) > and if it occurred because of non-existence of the temporary > table ignore it. In that case, the connection pool manager needs knowledge about how the tables are used and whether the database invalidates statements on DDL operations. I don't think we can expect the manager to have such knowledge. > b) In the case that the ConnectionPoolManager has not created > a temporary table and it is a genuine case of a invalid > PreparedStatement it needs to know it can make use of the > error occurred event that is raised. > > Thus throwing a error occurred event would allow the > ConnectionPoolManager to decide what needs to happen Again, I don't think the connection pool manager has enough information to decide this. It is the application that creates and accesses the table. The manager just does what the application tells it to do, and it has no way to find out whether the application will recreate the table later. > We are throwing the error occurred event only upon doing an execute > on the PreparedStatement. If the ConnectionPoolManager did know that > the temporary table or the table used in the PreparedStatement or in > the generalized case knew of a DDL invalidating a PreparedStatement > why would it do a execute on the PreparedStatement? Does'nt this > qualify as a faulty Pooling implementation? If it were using a > temporary table it would do an execute only during the time that the > temporary table exists. Narayanan No, I don't think this means the pool manager is faulty. It is the application, not the manager, that decides when it invokes execute().
        Hide
        V.Narayanan added a comment -

        Hi knut,
        thanx again for the comments!

        I see ur point. Getting the StatementErrorOccured event would mean that the ConnectionPoolManager will invalidate the PreparedStatement thus rendering it unusable to the overlying application. But then the application could have actually used the PreparedStatement again considering the fact that it still remains valid.

        seems like we should'nt be throwing the error occurred event in this case

        will wait until tommorrow to give people time to comment on this issue. If I don't receive any comments I am going ahead with removing this case

        thanx once again for ur patient answers,
        Narayanan

        Show
        V.Narayanan added a comment - Hi knut, thanx again for the comments! I see ur point. Getting the StatementErrorOccured event would mean that the ConnectionPoolManager will invalidate the PreparedStatement thus rendering it unusable to the overlying application. But then the application could have actually used the PreparedStatement again considering the fact that it still remains valid. seems like we should'nt be throwing the error occurred event in this case will wait until tommorrow to give people time to comment on this issue. If I don't receive any comments I am going ahead with removing this case thanx once again for ur patient answers, Narayanan
        Hide
        V.Narayanan added a comment -

        Objectives of this patch
        --------------------------------

        a) provide the imlementation for StatementEventListener methods in EmbedXAConnection40
        b) Modify TestUtil.java to return EmbedXADataSource40 when running with mustang
        c) remove testing for LSE_COMPILATION_PREFIX as hte prefix for the SQLState when throwing the Statement Error Occurred events.

        thanx
        Narayanan

        Show
        V.Narayanan added a comment - Objectives of this patch -------------------------------- a) provide the imlementation for StatementEventListener methods in EmbedXAConnection40 b) Modify TestUtil.java to return EmbedXADataSource40 when running with mustang c) remove testing for LSE_COMPILATION_PREFIX as hte prefix for the SQLState when throwing the Statement Error Occurred events. thanx Narayanan
        Hide
        Knut Anders Hatlen added a comment -

        The patch looks good and the tests ran cleanly. I reindented some parts of the code, since they had twice as much indentation as the surrounding code (does your editor use tab width eight instead of four?).

        Committed revision 396859.

        Show
        Knut Anders Hatlen added a comment - The patch looks good and the tests ran cleanly. I reindented some parts of the code, since they had twice as much indentation as the surrounding code (does your editor use tab width eight instead of four?). Committed revision 396859.
        Hide
        V.Narayanan added a comment -

        Thanx for the commit! My sincere apologies for the indentation errors. No I have actually set it to a tab width of four. Anyway I will verify once more.
        thanx once again
        Narayanan

        Show
        V.Narayanan added a comment - Thanx for the commit! My sincere apologies for the indentation errors. No I have actually set it to a tab width of four. Anyway I will verify once more. thanx once again Narayanan
        Hide
        V.Narayanan added a comment -

        Attaching the patch for providing the StatementEventListeners support for the client side. Also please find attached a html doc describing the work done.
        thanx
        Narayanan

        Show
        V.Narayanan added a comment - Attaching the patch for providing the StatementEventListeners support for the client side. Also please find attached a html doc describing the work done. thanx Narayanan
        Hide
        Knut Anders Hatlen added a comment -

        Looks good, but I have some questions/comments:

        • Should ClientJDBCObjectFactory40.newPreparedStatement() have
          returned a PreparedStatement40 object instead of PreparedStatement?
        • New field pooledConnnection_ in NetConnection is spelled incorrectly
          (three n's). It would also be good if it had a comment explaining
          what its purpose is.
        • New field pooledConnection_ in PreparedStatement could be final, I
          think.
        • Javadoc for ClientPooledConnection.onStatementErrorOccurred() is
          identical to onStatementClose().
        • Javadoc for ClientPooledConnection40.onStatementErrorOccurred()
          doesn't have @param tag for the second parameter.
        • Sentences in javadoc comments should start with a capital letter and
          end with a period, otherwise they are hard to read when the html is
          generated.
        • Many of the @param tags lack a description, or only the type of the
          parameter is put into the description.
        • The javadoc for many of the constructors of PreparedStatement and
          NetPreparedStatement start with "It has the ClientPooledConnection
          as one of its parameters". It would be better if the first sentence
          said something about what the constructors do, since the first
          sentence used in the summary when generating html.
        • Two of the ClientJDBCObjectFactory.newPreparedStatement() methods
          have a double set of javadoc comments.
        Show
        Knut Anders Hatlen added a comment - Looks good, but I have some questions/comments: Should ClientJDBCObjectFactory40.newPreparedStatement() have returned a PreparedStatement40 object instead of PreparedStatement? New field pooledConnnection_ in NetConnection is spelled incorrectly (three n's). It would also be good if it had a comment explaining what its purpose is. New field pooledConnection_ in PreparedStatement could be final, I think. Javadoc for ClientPooledConnection.onStatementErrorOccurred() is identical to onStatementClose(). Javadoc for ClientPooledConnection40.onStatementErrorOccurred() doesn't have @param tag for the second parameter. Sentences in javadoc comments should start with a capital letter and end with a period, otherwise they are hard to read when the html is generated. Many of the @param tags lack a description, or only the type of the parameter is put into the description. The javadoc for many of the constructors of PreparedStatement and NetPreparedStatement start with "It has the ClientPooledConnection as one of its parameters". It would be better if the first sentence said something about what the constructors do, since the first sentence used in the summary when generating html. Two of the ClientJDBCObjectFactory.newPreparedStatement() methods have a double set of javadoc comments.
        Hide
        V.Narayanan added a comment -

        Hi,
        Thank you for the thorough and detail review of the patch. I am addressing all the comments and reattaching the patch. Please point out any issues that you see in the patch which I shall fix and resubmit.
        thanx
        Narayanan

        Show
        V.Narayanan added a comment - Hi, Thank you for the thorough and detail review of the patch. I am addressing all the comments and reattaching the patch. Please point out any issues that you see in the patch which I shall fix and resubmit. thanx Narayanan
        Hide
        Knut Anders Hatlen added a comment -

        Hi Narayanan, I'm not able to apply your patch cleanly. Could you please resolve the conflicts and upload a new patch? Thanks.

        Show
        Knut Anders Hatlen added a comment - Hi Narayanan, I'm not able to apply your patch cleanly. Could you please resolve the conflicts and upload a new patch? Thanks.
        Hide
        V.Narayanan added a comment -

        fixed it! patch submitted by V.Narayanan broke patch submitted by V.Narayanan . patch for 1254 which got committed yesterday broke this one. I have fixed it now!

        Narayanan

        Show
        V.Narayanan added a comment - fixed it! patch submitted by V.Narayanan broke patch submitted by V.Narayanan . patch for 1254 which got committed yesterday broke this one. I have fixed it now! Narayanan
        Hide
        V.Narayanan added a comment -

        sorry for having made u go through the trouble of applying the broken patch. Missed the conflict when I submitted the patches.
        thanx
        Narayanan

        Show
        V.Narayanan added a comment - sorry for having made u go through the trouble of applying the broken patch. Missed the conflict when I submitted the patches. thanx Narayanan
        Hide
        Knut Anders Hatlen added a comment -

        Thanks Narayanan! Your new patch addresses all my comments. I have started the tests, and will commit when they have finished.

        Show
        Knut Anders Hatlen added a comment - Thanks Narayanan! Your new patch addresses all my comments. I have started the tests, and will commit when they have finished.
        Hide
        Knut Anders Hatlen added a comment -

        I get this diff when running the jdbc40 suite with DerbyNetClient:

                        • Diff file jdbc40/DerbyNetClient/jdbc40/StatementEventsTest.diff
            • Start: StatementEventsTest jdk1.6.0-beta2 DerbyNetClient jdbc40:jdbc40 2006-04-28 14:28:21 ***
              0 add
              > ..The Close Event did not occur
              > The Error Event did not occur
              Test Failed.
            • End: StatementEventsTest jdk1.6.0-beta2 DerbyNetClient jdbc40:jdbc40 2006-04-28 14:28:28 ***
        Show
        Knut Anders Hatlen added a comment - I get this diff when running the jdbc40 suite with DerbyNetClient: Diff file jdbc40/DerbyNetClient/jdbc40/StatementEventsTest.diff Start: StatementEventsTest jdk1.6.0-beta2 DerbyNetClient jdbc40:jdbc40 2006-04-28 14:28:21 *** 0 add > ..The Close Event did not occur > The Error Event did not occur Test Failed. End: StatementEventsTest jdk1.6.0-beta2 DerbyNetClient jdbc40:jdbc40 2006-04-28 14:28:28 ***
        Hide
        V.Narayanan added a comment -

        Hi Knut,
        "why do I keep doing this to myself ". Again a result of my patch for 1254. 1254 changes createNetConnection to use ClientJDBCObjectFactory to return an appropriate instance of NetConnection(or40). I had to pass the reference to ClientPooledConnection to this method. I have done it in the attached patch. I have also attached the diff between the previous and the current patch.

        Please accept my humble apologies for the inconvinience caused.

        Narayanan

        Show
        V.Narayanan added a comment - Hi Knut, "why do I keep doing this to myself ". Again a result of my patch for 1254. 1254 changes createNetConnection to use ClientJDBCObjectFactory to return an appropriate instance of NetConnection(or40). I had to pass the reference to ClientPooledConnection to this method. I have done it in the attached patch. I have also attached the diff between the previous and the current patch. Please accept my humble apologies for the inconvinience caused. Narayanan
        Hide
        V.Narayanan added a comment -

        Resolving earlier conflicts with 1235 and 1180 and submitting the patch again
        thanx
        Narayanan

        Show
        V.Narayanan added a comment - Resolving earlier conflicts with 1235 and 1180 and submitting the patch again thanx Narayanan
        Hide
        Knut Anders Hatlen added a comment -

        Committed revision 399644.

        Show
        Knut Anders Hatlen added a comment - Committed revision 399644.
        Hide
        V.Narayanan added a comment -

        Thanx for the commit knut !
        Narayanan

        Show
        V.Narayanan added a comment - Thanx for the commit knut ! Narayanan

          People

          • Assignee:
            V.Narayanan
            Reporter:
            Rick Hillegas
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development