commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Graham <grahamdavid1...@yahoo.com>
Subject RE: [DbUtils] Commit flag on QueryRunner
Date Mon, 10 Nov 2003 19:43:48 GMT

--- "Robinson, Jim" <Jim.Robinson@mpi.com> wrote:
> 
> David, I agree with you regarding flags.  This is a very nice package, I
> didn't mean to be critical.

I wasn't offended; we need as many people reviewing the code as possible. 
Thanks for your input.

> 
> I've only used EJBs and JTA, I've not been a developer so I may have
> some details wrong.  Others on this list can no doubt correct me.  To
> use either of these you need a transactionally aware data source.  I use
> JBoss which includes such a datasource.  All EJB containers provide one.
> For Tomcat I think you can use Tyrex, never tried.
> 
> At any rate transactional aspects of connections (commit, rollback) are
> managed by the container.  A transaction is started either upon entry of
> a demarcated EJB method (container managed transaction) or by explicit
> use of the UserTransaction interface
> (http://java.sun.com/products/jta/javadocs-1.0.1/javax/transaction/UserT
> ransaction.html). In the latter case you do something like
> 
>     userTransaction.begin();
> 
> The transaction is completed upon exit of the demarcated EJB method
> (container managed) or, if doing explicity transactions, by something
> like
> 
>     userTransaction.commit()   or   userTransaction.rollback()
> 
> Any database updates performed in between these events are associated
> with the transaction and will be committed or rolled back together.  You
> can, and often do, make many calls to datasource.getConnection() and
> connection.close() in between.  

That answered my next question :-).

> So you have decoupled the connection
> management from transaction management.  This is a very nice model to
> work with, especially the container managed version.  In that case there
> is no explicit transaction management in the code and you can rearrange,
> split, group transactions with ease.  The explicit version
> (UserTransaction) is slightly less nice because the explicity boundaries
> are in the code, but still much more flexible than doing it at an
> individual connection/update level.
> 
> So how does this work since ultimately it is done at the jdbc connection
> level?  Well, as I said I have not worked on implementation of
> containers.  I have however worked on emulations of them for development
> test frameworks.  One way to accomplish this is to keep a map of
> connections in your DataSource implementation with the thread as the
> key.  When a transaction is started you get a connection from the pool
> and store it in the map.  When the transaction ends you remove the
> thread key from the map.  In between getConnection() looks in the map
> for a connection and if it finds one that is returned.  I've left out
> some details and real Containers are surely more sophisticated, but that
> is a possible implementation.
> 
> Of course none of this works if you do explict calls to setAutoCommit,
> commit, rollback, etc.  In fact, you will get an exception if using some
> of these methods with a transactionally aware datasource if within a
> managed transaction.
> 
> Hopefully I've not mangled this explanation beyond comprehension. If I
> have perhaps someone could clarify.  Basically you cannot hijack
> container managed transactions by doing explict commits.  Removing the
> calls to commit, rollback, and setAutocommit would make the update
> methods perfectly compatible with either EJB managed transactions or
> UserTransaction.  If you can figure out a way to get this it would be
> very helpful to those of use using containers for transactions.  In the
> meantime I will probably try to subclass QueryRunner and override the
> update methods.

So maybe the best thing to do is remove those calls.  The Connection will
have to be in auto-commit mode or you must be using something like JTA
that handles transactions.  There's nothing to rollback anyways since it's
only a single update statement executing.  If an SQLException is thrown
during the update it obviously won't be committed and there are no other
changes to rollback.

Comments?

David

> 
> Regards,
> 
> Jim
> 
> 
> 
> 
> >You're right, I've never used EJB or JTA so this information is
> helpful.
> >How would the update() method look for JTA use?
> >
> >Obviously, QueryRunner isn't currently designed for this use case.  One
> >reason we changed these methods to normal members instead of statics is
> to
> >allow subclasses to override their behavior.  Wouldn't it be trivial to
> >create a JTA enabled QueryRunner subclass that just overrides the
> update()
> >method for your purposes?
> >
> >I'm not a big fan of flags changing class behavior like the proposed
> >solution because it leads to messy if/else statements.
> >
> >David
> >


__________________________________
Do you Yahoo!?
Protect your identity with Yahoo! Mail AddressGuard
http://antispam.yahoo.com/whatsnewfree

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message