3 Replies Latest reply on Jan 8, 2002 5:20 PM by davidjencks

    Question regarding (possible) distributed transaction

    zargon

      In my app there´s the following scenario:
      A "controller" session bean (SB) interacts with two entity (BMP) beans (EB1 & EB2), whereas the session bean acts as a facade to clients which never see the entity beans directly. Every entity bean is responsible for a specific table in the *SAME* database. Besides other things the controller session bean manages relationships between those two entity beans.

      Now the concrete transaction scenario: Transaction attributes are set to "required" for every bean involved. A client now calls the controller (SB) which in turn updates EB1 and afterwards EB2. According to spec this must now happen all in the same transaction context. If now something goes wrong within EB2 will the updates to EB1 also be rolled back!?

      I think the crucial point here is, wether this is regarded as a distributed transaction. Due to the fact, that most JDBC drivers dont support distrib. trx this would mean that the case above could not be handled correctly. However, it could be that (since the *SAME* ressource manager is involved) this is NOT regarded as a distrib. trx. In that case everything should work. Any hints!?

      P.S. I use Postgresql and I´m not quite sure if the JDBC driver handles distributed trx. However by investigating the source one can find many "XA" things in there ...!?

        • 1. Re: Question regarding (possible) distributed transaction
          davidjencks

          There are several aspects to 2pc/xa/distributed tx.

          Generally if everything changing data is in the same app and there is only one resource manager (database) you don't need any of them: w/jboss, the pooling code will make sure all work actually goes to the db over one connection, in one transaction, which can then be committed in 1 phase. This is your case.

          If there are 2 resource managers (rms) involved from one machine, you need 2pc, whereby when it's time to commit, the transaction manager first calls prepare on both, and if both return ok, then calls commit on both. The normal jboss tx manager will handle this ok if nothing crashes, however for crash recovery in the midst of the 2pc operation, it would need to record persistently which rms are involved in each transaction, which it does not do.

          2pc in java is available through xa semantics, which add a couple of things. One is the ability to do work to a rm in a transaction on any connection to that rm, which is essential for efficient pooling.

          Finally, if several app servers are participating in one tx, you have a distributed transaction. The different app servers can be using the same or different rms. If 2 app servers using 1 rm can see each others changes (within the same global tx) you have "tight coupling" if not "loose coupling". When it's time to commit, the initiating tx manager has to prepare all its rms, and tell the subsidiary tx managers to do likewise. When everyone has told the initiating tx manager "OK" it does the same with commit. All the tx managers have to persistently save which rms are involved in each prepare. The default jboss tx manager does not handle this at all: you can use the Tyrex plugin for this.

          • 2. Re: Question regarding (possible) distributed transaction
            zargon

            First, thanks David for clarifying things. Finally I can now distinguish between 2pc/distributed tx.

            > Generally if everything changing data is in the same
            > app and there is only one resource manager (database)
            > you don't need any of them: w/jboss, the pooling code
            > will make sure all work actually goes to the db over
            > one connection, in one transaction, which can then be
            > committed in 1 phase. This is your case.

            So what you say is that even when I fetch different connections from my Datasource in EB1 and EB2 the container recognizes this as belonging to the same trx (when same DB, and same rm) and uses the same underlying connection. Of course I have to release the connection in EB1 explicitely (con.close()) to make this work (could you confirm this!?)

            One last question:
            In older posts I heard you saying that you know of only a few JDBC drivers which fully integrate XA semantics for 2pc. I´ve found now a JDBC2.0 compliance doc for the postgresql driver: http://lab.applinet.nl/postgresql-jdbc/

            About XA it says:
            "Are XA datasources supported? This should be documented." :-(

            It would be interesting to hear about any success regarding XA with this driver. Have you any experiences!?

            • 3. Re: Question regarding (possible) distributed transaction
              davidjencks


              > So what you say is that even when I fetch different
              > connections from my Datasource in EB1 and EB2 the
              > container recognizes this as belonging to the same
              > trx (when same DB, and same rm) and uses the same
              > underlying connection. Of course I have to release
              > the connection in EB1 explicitely (con.close()) to
              > make this work (could you confirm this!?)

              I'm really only familiar with how the jca version of this works (i.e. default in jboss 3, optional and somewhat difficult setup in jboss 2.4) although I think the 2.4 code works similarly.

              If you have a "local transaction" (non-xa) adapter/driver, the ConnectionManager keeps track of whether there is a physical connection associated with the tx/thread, and for each request for a connection in that thread, gives you a [Connection] handle to the same physical connection. You don't need to close the handles before making calls to other ejbs, although you do need to make sure you don't hold a handle over a tx boundary. (this last is something I am working on fixing since we are not now spec compliant).

              If you do have an xa adapter/driver, it doesn't matter, since an xa driver can support work on any connection in any transaction at any time. The ConnectionManager just needs to make sure whatever physical connection it picks for you is enrolled in the correct transaction.
              >
              > One last question:
              > In older posts I heard you saying that you know of
              > only a few JDBC drivers which fully integrate XA
              > semantics for 2pc. I´ve found now a JDBC2.0
              > compliance doc for the postgresql driver:
              > http://lab.applinet.nl/postgresql-jdbc/
              >
              > About XA it says:
              > "Are XA datasources supported? This should be
              > documented." :-(
              >
              > It would be interesting to hear about any success
              > regarding XA with this driver. Have you any
              > experiences!?
              >
              I think I saw that also and concluded it was highly unlikely they had any xa support in their java driver. It's not that easy to write, especially if you do it the (extremely confusing IMHO) jdbc way. The only free xa driver I know of is the jca-based driver I wrote most of for Firebird. (there's a config for it for jboss 3 in the online manual).