BTM
  1. BTM
  2. BTM-117

XAException.XAER_RMERR should be treated as an error

    Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.1.2
    • Fix Version/s: 2.1.3
    • Number of attachments :
      0

      Description

      In the PostgreSQL JDBC driver the PGXAConnection.commitOnePhase() (and other methods too) throws an XAException with the error code XAException.XAER_RMERR when a server-side error occurs during database commit. This is not handled in Committer.CommitJob.handleXAException()'s `switch (xaException.errorCode)'. The result of this behavior is that the transaction manager reports that the transaction is successfully committed but the underlying database transaction remains open.

        Activity

        Hide
        Ludovic Orban added a comment -

        Yes, that's a bug in the 1PC optimization's error handling logic. I'll fix this ASAP.

        Show
        Ludovic Orban added a comment - Yes, that's a bug in the 1PC optimization's error handling logic. I'll fix this ASAP.
        Hide
        Ludovic Orban added a comment -

        I've just pushed the changes to fix this bug and published a new 2.1.3-SNAPSHOT version in codehaus' snapshots repo.

        Could you please have a look at it and let me know if this works up to your expecations? As a reminder, the instructions to access codehaus' snapshots repo is at http://docs.codehaus.org/display/BTM/Maven2#Maven2-Earlyversions

        Show
        Ludovic Orban added a comment - I've just pushed the changes to fix this bug and published a new 2.1.3-SNAPSHOT version in codehaus' snapshots repo. Could you please have a look at it and let me know if this works up to your expecations? As a reminder, the instructions to access codehaus' snapshots repo is at http://docs.codehaus.org/display/BTM/Maven2#Maven2-Earlyversions
        Hide
        TEUBEL György added a comment -

        It works well, the TransactionManager.commit() throws a RollbackException which the caller can catch. And additionally it can extract the wrapped SQLException's information from it.

        But there is an other problem: the transaction manager's rollback() method throws an IllegalStateException with a message "no transaction started on this thread" after the commit() throws a RollbackException so the failed transaction cannot be rolled back properly (and it will not rolled back internally). If this is a separate issue then I will create an new issue about it.

        Show
        TEUBEL György added a comment - It works well, the TransactionManager.commit() throws a RollbackException which the caller can catch. And additionally it can extract the wrapped SQLException's information from it. But there is an other problem: the transaction manager's rollback() method throws an IllegalStateException with a message "no transaction started on this thread" after the commit() throws a RollbackException so the failed transaction cannot be rolled back properly (and it will not rolled back internally). If this is a separate issue then I will create an new issue about it.
        Hide
        Ludovic Orban added a comment -

        I don't think there's any other problem, at least if I understand you right.

        TransactionManager.commit() terminates the transaction, no matter what. Its goal is to commit it but if it fails to, it can throw RollbackException after cleaning up the transaction.

        In a nutshell, there's no need to call TransactionManager.rollback() when TransactionManager.commit() has thrown an exception: the commit method already did the job of the rollback method and that why it threw RollbackException: to indicate this fact.

        This is all strictly compliant with the JTA spec.

        Show
        Ludovic Orban added a comment - I don't think there's any other problem, at least if I understand you right. TransactionManager.commit() terminates the transaction, no matter what. Its goal is to commit it but if it fails to, it can throw RollbackException after cleaning up the transaction. In a nutshell, there's no need to call TransactionManager.rollback() when TransactionManager.commit() has thrown an exception: the commit method already did the job of the rollback method and that why it threw RollbackException: to indicate this fact. This is all strictly compliant with the JTA spec.
        Hide
        TEUBEL György added a comment -

        It's alright when the commit() fails with a RollbackException then it rolls back the actual transaction, but the problem is that it does not do this. The underlying database transaction remains uncommitted/waits for to be rolled back.

        Show
        TEUBEL György added a comment - It's alright when the commit() fails with a RollbackException then it rolls back the actual transaction, but the problem is that it does not do this. The underlying database transaction remains uncommitted/waits for to be rolled back.
        Hide
        Ludovic Orban added a comment -

        If the underlying database transaction really remains uncommitted, then there is a bug in your database and/or JDBC driver.

        Quoting http://docs.oracle.com/javaee/1.4/api/javax/transaction/xa/XAResource.html#commit%28javax.transaction.xa.Xid,%20boolean%29 :

        If the resource manager did not commit the transaction and the parameter onePhase is set to true, the resource manager may throw one of the XA_RB* exceptions. Upon return, the resource manager has rolled back the branch's work and has released all held resources.

        What version of Postgres and its JDBC driver are you using? With that information I'll be able to investigate the driver's source code to try to figure out if that's a geniune bug or a mis-understanding of the JTA spec.

        I suggest you to report this problem to the postgres JDBC developers and copy me on the conversation so I'll be able to follow on what's going on and eventually argue if that's needed.

        Show
        Ludovic Orban added a comment - If the underlying database transaction really remains uncommitted, then there is a bug in your database and/or JDBC driver. Quoting http://docs.oracle.com/javaee/1.4/api/javax/transaction/xa/XAResource.html#commit%28javax.transaction.xa.Xid,%20boolean%29 : If the resource manager did not commit the transaction and the parameter onePhase is set to true, the resource manager may throw one of the XA_RB* exceptions. Upon return, the resource manager has rolled back the branch's work and has released all held resources. What version of Postgres and its JDBC driver are you using? With that information I'll be able to investigate the driver's source code to try to figure out if that's a geniune bug or a mis-understanding of the JTA spec. I suggest you to report this problem to the postgres JDBC developers and copy me on the conversation so I'll be able to follow on what's going on and eventually argue if that's needed.
        Hide
        TEUBEL György added a comment -

        You are right, I did not read the JTA documentation properly.

        I use the most recent stable version of the PostgreSQL JDBC driver (9.1-901). It's XAResource implementation is the org.postgresql.xa.PGXAConnection class. It contains a commitOnePhase() method which is called when the commit()'s onePhase parameter is true.
        And it does not roll back the transaction when a SQLException occurs.

        I dig around a little if it's really a bug and report it to the PostgreSQL JDBC driver developers.

        Show
        TEUBEL György added a comment - You are right, I did not read the JTA documentation properly. I use the most recent stable version of the PostgreSQL JDBC driver (9.1-901). It's XAResource implementation is the org.postgresql.xa.PGXAConnection class. It contains a commitOnePhase() method which is called when the commit()'s onePhase parameter is true. And it does not roll back the transaction when a SQLException occurs. I dig around a little if it's really a bug and report it to the PostgreSQL JDBC driver developers.
        Hide
        TEUBEL György added a comment -

        I've created an issue about it. If you want to you can follow it here: https://github.com/pgjdbc/pgjdbc/issues/2

        Show
        TEUBEL György added a comment - I've created an issue about it. If you want to you can follow it here: https://github.com/pgjdbc/pgjdbc/issues/2

          People

          • Assignee:
            Ludovic Orban
            Reporter:
            TEUBEL György
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: