ibatis-user-java mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Guy Rouillier <guyr-...@burntmail.com>
Subject Re: Transaction management in iBATIS 3 inside an EJB (3.1) container
Date Mon, 19 Apr 2010 17:33:47 GMT
I haven't been following this thread closely, but with JBoss at least, 
you have the option of configuring datasources as no-transaction: 
no-tx-datasource.  With this type of datasource, you are free to call 
commit and rollback yourself.  With container-managed transactions, you 
should not be calling commit or rollback.  I've erroneously done so, and 
JBoss generates an error saying that these methods are illegal on a 
container managed transaction.

Regarding your thoughts about a smart resource manager, that is indeed 
what happens.  Remember that datasource may be retrieved and closed any 
number of times during the processing of a single EJB method.  During 
the execution of single EJB method, the container is required by the 
spec to return the same physical connection each time getConnection() is 
invoked, so that all database activity within that method (which can of 
course call other methods) is guaranteed to be within the same transaction.

Only when the EJB method completes does the container do the commit or 
rollback and then returns the connection to the pool as available for use.

Since iBATIS can't possible determine that it is being used in a 
container-managed transaction, if you want to support that, I would 
think the only possibility is to provide an optional parameter in the 
data source configuration to indicate that.  In such cases, iBATIS 
should probably no-op commit and rollback.

On 4/19/2010 11:15 AM, Clinton Begin wrote:
> Thanks Adinath.
> This will all help.  Let's figure this out together.
> The odd thing for me is this.  A typical transaction lifecycle (be it
> global or otherwise would be:
> *  Open Connection
> *  Do Work
> *  Commit or Rollback
> *  Close Connection (even if this implies a return to the connection pool)
> The problem with calling close on a connection that's globally managed
> is that it changes the lifecycle to:
> *  Open Connection
> *  Do Work
> * >> Close Connection (even if this implies a return to the connection pool)
> *  Commit or Rollback
> Now I suppose a smart resource manager controlling the transaction would
> know better than to actually return the connection to the pool until the
> worker thread is finished and the transaction is either committed or
> rolled back, but I'm not entirely confident that all app servers are
> that smart.  As you noted, glassfish doesn't even warn you when you call
> commit in a managed transaction (most resource managers would throw an
> exception if commit or rollback were called).  I wouldn't be surprised
> if this is the reason you're getting intermittent IllegalStateExceptions.
> I'm going to do a little more reading tonight on JEE 6 standard behavior
> to see if there's one approach we can trust.
> The most empirical evidence of the proper behavior would be iBATIS 2,
> which calls close.  But I normally don't remove code without reason
> (although it has happened ;-).
> I'll check into this tonight or tomorrow at the latest.
> Cheers,
> Clinton
> On Mon, Apr 19, 2010 at 1:26 AM, Adinath <adinath@acciente.com
> <mailto:adinath@acciente.com>> wrote:
>     Clinton,
>     On Sun, Apr 18, 2010 at 2:45 PM, Clinton Begin
>     <clinton.begin@gmail.com <mailto:clinton.begin@gmailcom>> wrote:
>         You did the right thing... iBATIS transaction managers are meant
>         to be easy to implement yourself.
>     Yes, they are easy to implement!
>         That said, this was a matter of constant debate back in the good
>         old days when none of the standards were implemented
>         consistently.  I'm still not sure if they are.
>         Some app servers would complain if iBATIS closed the connection,
>         because if some downstream process needed a connection,
>         theoretically it was supposed to use the same one (which would
>         be closed by that time). I think the trick is to ensure that
>         you're using a container managed DataSource.  Are you retrieving
>         a DataSource configured by GlassFish from a JNDI context (in
>         other words, a container manged DataSource)?  Or are you just
>         using the iBATIS built-in SimpleDataSource?
>     Yes I am using using a container managed datasource (GlassFish v3
>     managing a DB2 v9.7 connection), looked up via JNDI. I create the
>     iBATIS session factory using SqlSessionFactoryBuilder and the
>     related classes (i.e. no XML config file).
>     I
>         I would expect a container managed DataSource to lazily
>         initialize a connection for any one worker thread, and continue
>         to provide that same connection to any requester for that
>         particular DataSource.  Then I'd expect it to close that
>         connection at the end of the entire workflow.
>     My experience with GlassFish is that the connection needs to be
>     closed to be returned to the pool.
>     With GlassFish I wrote a set of tests and established that if you
>     call commit() on a JDBC connection returned by the container managed
>     datasource it causes an commit (thru to the driver), defeating the
>     EJB transaction.
>     There are 2 other issues I ommitted in my original post, for
>     clarity. I suspect these 2 issues have nothing to do with IBATIS,
>     but I am just sharing FYI (just in case).
>     *Issue #1*
>     In the close() method of my custom iBATIS transaction class I would
>     transiently (about every 4 times) get IllegalStateException with
>     "state.isBusy() : false" in the message when I call
>     connection.close(). Some posts pointed that this happens when the
>     connection is already closed. But I have verified using the debugger
>     that this does not apply, the connection is open and isClosed()
>     returns false. The fix for now is to catch the IllegalStateException
>     the close() and ignore it! :(
>     *Issue #2*
>     The other issue is rather unnerving, I am reluctant to share it
>     since it is a little winded, but thought perhaps it may help someone
>     else. This too I suspect has nothing to do with iBATIS. It is as
>     follows:
>     - there is a stateful session bean (sfsb) A that has a reference to
>     another sfsb B
>     - there is a method in sfsb A, say methodOfA, which inserts a row
>     using iBATIS
>     - there is a method in sfsb B, say methodOfB, which inserts a row
>     using direct JDBC
>        - methodOfB() also uses a container managed DataSource to
>     retrieve a connection and does connection.close() before returning
>     - now the logic in methodOfA() looks like below:
>     public void methodOfA()
>     {
>        session = sessionFactory.openSession()
>        boolean commit = false;
>        try
>        {
>           mapper = session.getMapper( UserMapper.class);
>           someID = beanB.methodOfB();
>           // set value for user
>           user = new User();
>           user.setOtherStuff() ...
>           user.setSomeID( someID );
>           // insert row for new user
>           mapper.insertUser( user );
>           commit = true;
>        }
>        finally
>        {
>            sessionclose();
>            if ( ! commit )
>            {
>               sessionCtx.setRollbackOnly();
>            }
>        }
>     }
>     The issue here is that if I set a debug breakpoint at the line with
>     mapper.insertUser( user ),I sometimes see the update by
>     referenceToB.methodInB() get commited to the database!! (checked via
>     a DB2 SQL console) This happened late Friday and I have not had a
>     chance to look at since. I think the culprit here is GlassFish, I
>     suspect that this happens only during debugging (need to verify this).
>     On a final note, I have used iBATIS 2 on a previous project and
>     iBATIS 3 on the current one. Even with IBATIS 2 I thought it was an
>     incredible piece of work, well-thought out and a pleasure to use.
>     Especially love the support for dynamic SQL, and the type handler
>     callbacks. Excellent work!
>     Best,
>     Adi
>     --
>     Acciente, LLC
>     Systems Architecture and Software Design
>     www.acciente.com <http://www.acciente.com>
>     www.inductionframework.org <http://www.inductionframework.org>

Guy Rouillier

To unsubscribe, e-mail: user-java-unsubscribe@ibatis.apache.org
For additional commands, e-mail: user-java-help@ibatis.apache.org

View raw message