? xaer_rmerr-only-if-xact-does-not-exist-1.patch
? xaer_rmerr-only-if-xact-does-not-exist-2.patch
Index: org/postgresql/util/PSQLState.java
===================================================================
RCS file: /cvsroot/jdbc/pgjdbc/org/postgresql/util/PSQLState.java,v
retrieving revision 1.14
diff -c -r1.14 PSQLState.java
*** org/postgresql/util/PSQLState.java	31 Mar 2011 03:06:39 -0000	1.14
--- org/postgresql/util/PSQLState.java	29 Jun 2011 16:07:57 -0000
***************
*** 88,93 ****
--- 88,94 ----
  
      public final static PSQLState SYNTAX_ERROR = new PSQLState("42601");
      public final static PSQLState UNDEFINED_COLUMN = new PSQLState("42703");
+     public final static PSQLState UNDEFINED_OBJECT = new PSQLState("42704");
      public final static PSQLState WRONG_OBJECT_TYPE = new PSQLState("42809");
      public final static PSQLState NUMERIC_CONSTANT_OUT_OF_RANGE = new PSQLState("42820");
      public final static PSQLState DATA_TYPE_MISMATCH = new PSQLState("42821");
Index: org/postgresql/xa/PGXAConnection.java
===================================================================
RCS file: /cvsroot/jdbc/pgjdbc/org/postgresql/xa/PGXAConnection.java,v
retrieving revision 1.17
diff -c -r1.17 PGXAConnection.java
*** org/postgresql/xa/PGXAConnection.java	31 Mar 2011 06:25:42 -0000	1.17
--- org/postgresql/xa/PGXAConnection.java	29 Jun 2011 16:07:57 -0000
***************
*** 498,504 ****
          }
          catch (SQLException ex)
          {
!             throw new PGXAException(GT.tr("Error committing prepared transaction"), ex, XAException.XAER_RMERR);
          }
      }
  
--- 498,525 ----
          }
          catch (SQLException ex)
          {
! 	    // Per JTA spec, we should return XAER_RMERR only if the
! 	    // prepared transaction has permanently failed and can never be
! 	    // committed. In that case the fundamental contract of two-phase
! 	    // commit that if a transaction has been prepared, it can
! 	    // eventually be committed, has been broken. In all other cases,
! 	    // where the commit fails but the transaction stays in prepared
! 	    // state, we should return XA_RETRY.
! 	    //
! 	    // If the prepared transaction exists, but commit fails for any
! 	    // other reason, we assume that the commit might succeed if
! 	    // retried later. The server uses sqlstate UNDEFINED_OBJECT
! 	    // (42704) if the prepared transcation doesn't exist, so we
! 	    // check for that. The same sqlstate is used for all kinds of
! 	    // missing object errors, but in case of COMMIT PREPARED, it's
! 	    // reasonable to assume that if you get that error code, it's the
! 	    // prepared transaction that's missing.
! 	    int xaerrcode;
! 	    if (ex.getSQLState().equals(PSQLState.UNDEFINED_OBJECT))
! 		xaerrcode = XAException.XAER_RMERR;
! 	    else
! 		xaerrcode = XAException.XA_RETRY;
!             throw new PGXAException(GT.tr("Error committing prepared transaction"), ex, xaerrcode);
          }
      }
  
