Re: a simple example of XA (not working)

Поиск
Список
Период
Сортировка
От Heikki Linnakangas
Тема Re: a simple example of XA (not working)
Дата
Msg-id 4674E56C.8060802@enterprisedb.com
обсуждение исходный текст
Ответ на a simple example of XA (not working)  (Luca Ferrari <fluca1978@infinito.it>)
Ответы Re: a simple example of XA (not working)  (Luca Ferrari <fluca1978@infinito.it>)
Re: a simple example of XA (not working)  (Kris Jurka <books@ejurka.com>)
Список pgsql-jdbc
Luca Ferrari wrote:
> Hi all,
> I'm trying to build a simple "manual" example of the use of the XA extension,
> the following is the code:
>
>     PGXADataSource dataSource = new PGXADataSource();
>     dataSource.setDatabaseName("hrpm");
>     dataSource.setUser("luca");
>     dataSource.setServerName("localhost");
>
>     XAConnection connection = dataSource.getXAConnection();
>     System.out.println("Connesso!");
>     XAResource resource = connection.getXAResource();
>     MyXid identifier = new MyXid();
>     identifier.setBranchQualifier(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05});
>     identifier.setGlobalTransactionId(new byte[] {0x05, 0x04, 0x03, 0x02, 0x01});
>     identifier.setFormatId(100);
>
>     try{
>         resource.start(identifier, XAResource.TMNOFLAGS);
>
>
>         Connection jdbcConnection = connection.getConnection();
>         Statement statement = jdbcConnection.createStatement();
>         String sql = "INSERT INTO ...";
>         int inserted = statement.executeUpdate(sql);
>
>         resource.end(identifier, XAResource.TMSUCCESS);
>
>         int commit = resource.prepare(identifier);
>         if( commit == XAResource.XA_OK )
>         resource.commit(identifier, false);
>         else
>         resource.rollback(identifier);
>
>
> now the exception that is raised when the program commits the transaction is
> the following:
>
> javax.transaction.xa.XAException: org.postgresql.util.PSQLException: ERROR:
> prepared transaction with identifier "100_BQQDAgE=_AQIDBAU=" does not exist
>     at org.postgresql.xa.PGXAConnection.commitPrepared(PGXAConnection.java:412)
>     at org.postgresql.xa.PGXAConnection.commit(PGXAConnection.java:339)
>
> and the log of the database says:
>
> 2007-06-16 16:05:48 CEST LOG:  execute <unnamed>: INSERT INTO ....
> 2007-06-16 16:05:48 CEST LOG:  execute <unnamed>: PREPARE
> TRANSACTION '100_BQQDAgE=_AQIDBAU='
> 2007-06-16 16:05:48 CEST WARNING:  non c'è nessuna transazione in corso
> 2007-06-16 16:05:48 CEST LOG:  execute <unnamed>: COMMIT
> PREPARED '100_BQQDAgE=_AQIDBAU='
> 2007-06-16 16:05:48 CEST ERROR:  prepared transaction with
> identifier "100_BQQDAgE=_AQIDBAU=" does not exist
> 2007-06-16 16:05:48 CEST STATEMENT:  COMMIT PREPARED '100_BQQDAgE=_AQIDBAU='
> 2007-06-16 16:05:49 CEST LOG:  unexpected EOF on client connection
>
> that is an error since it seems no one transaction has been started. However,
> debugging the application, I've seen that the driver disables the autocommit
> mode, thus where is the problem here?
> I'm sorry, I'm not a XA expert, just learning.

This seems to be an undesired side-effect of this patch that was
committed in December:

> date: 2006/12/01 10:13:46;  author: jurka;  state: Exp;  lines: +19 -22
> A XAConnections default autocommit state should be true.  The
> driver was previously setting autocommit to false and assuming it
> would stay that way.  This caused two problems.  First, some
> applications expected to be able to issue local autocommit
> transactions prior to begin().  Second, some TMs (Geronimo) set the
> autocommit state to true themselves, which causes problems as the
> driver did not expect it to be changed.  This patch correctly disables
> and enables autocommit around begin, prepare, commit, and rollback
> methods.

getConnection sets autocommit to false, so even though start set it to
true, it's reset to false in the call to getConnection. Attached patch
fixes that by explicitly setting autocommit to the right mode in
PGXAConnection.getConnection.

As a work-around, just call jdbcConnection.setAutoCommit(false) in your
program before executing any queries.

--
   Heikki Linnakangas
   EnterpriseDB   http://www.enterprisedb.com
Index: org/postgresql/xa/PGXAConnection.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/xa/PGXAConnection.java,v
retrieving revision 1.10
diff -c -r1.10 PGXAConnection.java
*** org/postgresql/xa/PGXAConnection.java    1 Dec 2006 11:53:02 -0000    1.10
--- org/postgresql/xa/PGXAConnection.java    17 Jun 2007 07:40:03 -0000
***************
*** 61,67 ****

      public Connection getConnection() throws SQLException
      {
!         return super.getConnection();
      }

      public XAResource getXAResource() {
--- 61,80 ----

      public Connection getConnection() throws SQLException
      {
!         Connection conn = super.getConnection();
!
!     // When we're outside an XA transaction, autocommit
!     // is supposed to be true, per usual JDBC convention.
!     // When an XA transaction is in progress, it should be
!     // false.
!
!     // super.getConnection resets autocommit to true, so we
!     // have to set it to false before handing the connection
!     // to the caller, if an XA transaction is active.
!     if(state == STATE_ACTIVE)
!         conn.setAutoCommit(false);
!
!     return conn;
      }

      public XAResource getXAResource() {

В списке pgsql-jdbc по дате отправления:

Предыдущее
От: Luca Ferrari
Дата:
Сообщение: a simple example of XA (not working)
Следующее
От: Luca Ferrari
Дата:
Сообщение: Re: a simple example of XA (not working)