Re: XA rollback problem
On Mon, 24 Apr 2006, Kris Jurka wrote:
Indeed the closing before committing is a problem. The PGXADatasource code
is piggybacking on the PooledConnection code. When you close a
PooledConnection a rollback occurs so that the connection can be reused. For
the XAConnection it must put the connection into a pending-closed state and
wait for the transaction manager to commit or rollback the connection. It'll
be a little tricky to make this work for both the PooledConnection and
XAConnection cases, but I'll take a look at that this week.
I have applied the attached patch to the 8.1 and head cvs branches which
fixes it for me.
I've uploaded some jars for you to test here, and a new official release
should hopefully be out within the week.
http://www.ejurka.com/pgsql/jars/nb/
Kris Jurka
? org/postgresql/xa/.PGXADataSource.java.swp
Index: org/postgresql/ds/common/PooledConnectionImpl.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/ds/common/PooledConnectionImpl.java,v
retrieving revision 1.10
diff -c -r1.10 PooledConnectionImpl.java
*** org/postgresql/ds/common/PooledConnectionImpl.java 17 Jan 2005 10:59:04 -0000 1.10
--- org/postgresql/ds/common/PooledConnectionImpl.java 26 Apr 2006 18:47:26 -0000
***************
*** 32,47 ****
private List listeners = new LinkedList();
private Connection con;
private ConnectionHandler last;
! private boolean autoCommit;
/**
* Creates a new PooledConnection representing the specified physical
* connection.
*/
! public PooledConnectionImpl(Connection con, boolean autoCommit)
{
this.con = con;
this.autoCommit = autoCommit;
}
/**
--- 32,54 ----
private List listeners = new LinkedList();
private Connection con;
private ConnectionHandler last;
! private final boolean autoCommit;
! private final boolean isXA;
/**
* Creates a new PooledConnection representing the specified physical
* connection.
*/
! public PooledConnectionImpl(Connection con, boolean autoCommit, boolean isXA)
{
this.con = con;
this.autoCommit = autoCommit;
+ this.isXA = isXA;
+ }
+
+ public PooledConnectionImpl(Connection con, boolean autoCommit)
+ {
+ this(con, autoCommit, false);
}
/**
***************
*** 306,312 ****
return null;
SQLException ex = null;
! if (!con.getAutoCommit())
{
try
{
--- 313,319 ----
return null;
SQLException ex = null;
! if (!isXA && !con.getAutoCommit())
{
try
{
Index: org/postgresql/test/xa/XADataSourceTest.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/test/xa/XADataSourceTest.java,v
retrieving revision 1.5
diff -c -r1.5 XADataSourceTest.java
*** org/postgresql/test/xa/XADataSourceTest.java 24 Nov 2005 02:31:44 -0000 1.5
--- org/postgresql/test/xa/XADataSourceTest.java 26 Apr 2006 18:47:26 -0000
***************
*** 142,147 ****
--- 142,160 ----
xaRes.commit(xid, false);
}
+ public void testCloseBeforeCommit() throws Exception {
+ Xid xid = new CustomXid(5);
+ xaRes.start(xid, XAResource.TMNOFLAGS);
+ assertEquals(1, conn.createStatement().executeUpdate("INSERT INTO testxa1 VALUES (1)"));
+ conn.close();
+ xaRes.end(xid, XAResource.TMSUCCESS);
+ xaRes.commit(xid, true);
+
+ ResultSet rs = _conn.createStatement().executeQuery("SELECT foo FROM testxa1");
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt(1));
+ }
+
public void testRecover() throws Exception {
Xid xid = new CustomXid(12345);
xaRes.start(xid, XAResource.TMNOFLAGS);
Index: org/postgresql/xa/PGXAConnection.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/xa/PGXAConnection.java,v
retrieving revision 1.6
diff -c -r1.6 PGXAConnection.java
*** org/postgresql/xa/PGXAConnection.java 24 Nov 2005 07:25:16 -0000 1.6
--- org/postgresql/xa/PGXAConnection.java 26 Apr 2006 18:47:26 -0000
***************
*** 50,56 ****
PGXAConnection(BaseConnection conn) throws SQLException
{
! super(conn, false);
this.conn = conn;
this.conn.setAutoCommit(false);
this.state = STATE_IDLE;
--- 50,56 ----
PGXAConnection(BaseConnection conn) throws SQLException
{
! super(conn, false, true);
this.conn = conn;
this.conn.setAutoCommit(false);
this.state = STATE_IDLE;
Home |
Main Index |
Thread Index