ibatis-user-java mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Clinton Begin" <clinton.be...@gammagarage.com>
Subject Proper transaction code pattern (was: Autocommit not properly handled in Ibatis)
Date Mon, 22 Jan 2007 17:40:02 GMT
Hi everyone,

Reading through the original thread, there is more than one person
confused by sessions and transactions, so here's some clarification.

There are four levels of control you can have over iBATIS
transactions.  They are:

#1 First is single statement, automatic transaction.  In this case,
you execute one statement that gets committed (or rolled back)
automatically by iBATIS.  This behaves like JDBC "auto-commit", but it
definitely doesn't use it.  iBATIS always explicitly calls
commit/rollback.  An example of this single statement approach is:

sqlMapper.insert("insertPerson",somePerson);

You don't need a try/finally block or anything.  It's all self
contained.  This is one transaction.

#2 The second is multi-statement manual transaction mode.  In this
case you have multiple statements you want to succeed or fail as a
group.  If one statement fails, they all get rolled back.  This is the
most common case for update statements, but can also improve the
performance and consistency of multiple queries in some cases.  The
example is:

try {
  sqlMapper.startTransaction();
  sqlMapper.insert("insertPerson",somePerson);
  sqlMapper.update("updatePerson",someOtherPerson);
  sqlMapper.delete("deletePerson",anotherPerson);
  sqlMapper.commitTransaction();
} finally {
  sqlMapper.endTransaction();
}

There's no explicit call to rollback().  iBATIS knows if you've called
commit() indicating a successful transaction, otherwise it calls
rollback.  This allows you to use try/finally semantics instead of
try/catch (which can get messy).  You must ensure that this is always
in a try/finally block as above, otherwise you risk connection leaks.

#3 The third approach is to manage sessions manually.  In the last two
cases sessions were managed automatically.  Sometimes you need to do
this for greater control of the broader iBATIS usage scope, but you
might also use it to pass your own connection to iBATIS (openSession()
can take a connection as a parameter).  Here's an example:

SqlMapSession session = sqlMap.openSession()
try {
   session.startTransaction()
   session.insert("insertPerson",somePerson);
   session.update("updatePerson",someOtherPerson);
   session.delete("deletePerson",anotherPerson);
   session.commitTransaction();
 } finally {
   try {
     session.endTransaction();
   } finally {
     session.close();
   }
   // Generally your session scope would be in a wider context and therefore the
   // ugly nested finally block above would not be there.  Realize that sessions
   // MUST be closed if explicitly opened (via openSession()).
 }

As you can see, there's definitely more work and more code involved
with managing sessions manually...it's therefore pretty rare.  If you
do, you'll usually hide it in some abstract class or perhaps even in a
separate layer of the application.  As the comment above says, doing
so will also avoid the need for a nested try/finally block (in C#
using blocks make this a lot cleaner too!).

#4 Finally, there's 3rd Party session/transaction management.  This is
the case if you're using Spring DAO, iBATIS DAO, or some other higher
level persistence framework that has an iBATIS "plug-in".  I won't
bother with an example, as you're better off looking them up.  The one
we generally recommend is Spring DAO.

I hope that helps.  This is all documented both in the JavaDocs and
the user guide (this is almost a cut and paste from the javadoc).  Let
us know if and how we can make it more clear.

Cheers,
Clinton

On 1/22/07, Clinton Begin <clinton.begin@gammagarage.com> wrote:
> Cornel,
>
> Richard is right.  You're unfortunately mistaken.  The following is an
> excerpt from the documentation you responded with:
>
> 'If a connection is in auto-commit mode, then all its SQL statements
> will be executed and committed as individual transactions. Otherwise,
> its SQL statements are grouped into transactions that are terminated
> by a call to either the method commit or the method rollback."
>
> iBATIS always commits or rolls back transactions explicitly with
> commit() and rollback().
>
> Clinton
>
> On 1/22/07, Cornel Antohi <cantohi@kepler-rominfo.com> wrote:
> >
> >
> > Hi Richard,
> >
> > I do not agree with you:
> > http://java.sun.com/j2se/1.3/docs/api/java/sql/Connection.html#setAutoCommit(boolean)
> >
> > Thank you,
> > Cornel
> >
> > ----- Original Message -----
> > From: Yee, Richard K CTR DMDC
> > To: 'user-java@ibatis.apache.org'
> >
> > Sent: Monday, January 22, 2007 6:42 PM
> > Subject: RE: Autocommit not properly handled in Ibatis.
> >
> >
> > Antohi,
> > It looks to me that the code does exactly what Clinton says. If autocommit
> > is on, iBATIS turns it off and thus does not use autocommit to commit
> > changes to the DB.
> >
> > -Richard
> >
> >
> >
> > -----Original Message-----
> > From: Cornel Antohi [mailto:cantohi@kepler-rominfo.com]
> > Sent: Monday, January 22, 2007 2:37 AM
> > To: user-java@ibatis.apache.org
> > Subject: Re: Autocommit not properly handled in Ibatis.
> >
> >
> > Hi Clinton,
> >
> > 1) What do you mean by "iBATIS never uses AutoCommit"? Here is what I found
> > in:
> >
> > com.ibatis.sqlmap.engine.transaction.jdbc.JdbcTransaction
> > --> private void init() throws SQLException, TransactionException
> > // AutoCommit
> > if (connection.getAutoCommit()) {
> >     connection.setAutoCommit(false);
> > }
> >
> >
> > Thank you,
> > Cornel
> >
> > ----- Original Message -----
> > From: "Clinton Begin" <clinton.begin@gmail.com>
> > To: <user-java@ibatis.apache.org>
> > Sent: Friday, January 19, 2007 8:52 AM
> > Subject: Re: Autocommit not properly handled in Ibatis.
> >
> > A few things:
> >
> > 1) iBATIS never uses AutoCommit.
> >
> > 2) setCommitRequired has nothing to do with AutoCommit.  iBATIS uses
> > deferred commits to avoid unecessary commits when no non-queries have
> > been issued.  And setCommitRequired is actually parameterized and can
> > be set with <transactionManager ... commitRequired="true">
> >
> > 3) You'll need to post your code so we can see what it's doing.  Are
> > you calling startTransaction()?  Are you using setUserConnection?  Or
> > openSession(conn)?
> >
> > I'm sure with the right information we can resolve this for you easily.
> >
> > Clinton
> >
> > On 1/18/07, Yuvraj Shinde <Yuvraj.Shinde@sos.sungard.com> wrote:
> > >
> > >
> > >
> > >
> > > Hi all,
> > >
> > >
> > >
> > >    I want to know how to handle auto commit in ibatis.if I am saving two
> > > records and if I get an exception while saving second record the first
> > > record saved should be rolled back.
> > >
> > >   But ibatis is saving the first record. How I should handle this even
> > > though the auto commit property is explicitly set to false.
> > >
> > >
> > >
> > >    Even though AutoCommit value is set to false. Rollback of Transaction
> > is
> > > not working.
> > >
> > >    I found one Issue in GeneralStatement.java.
> > >
> > >    On line 52  request.getSession().setCommitRequired(true);
> > >
> > >
> > >
> > >    Here Auto commit is hard coded it should be parameterized so that it
> > will
> > > take value from "Auto commit" property of  SqlMapConfig.xml.
> > >
> > >    Please correct me if I am wrong.please send me a solution.
> > >
> > >
> > >
> > > Regards
> > >
> > > Yuvrajs
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > > Yuvraj Shinde * Senior Software Engineer -  Zainet*  SunGard * Offshore
> > > Services *
> > >  Pride Portal,CTS No 103A/5A/1A/1B Bhamburda,Senapati Bapat Road,
> > > shivajinagar,Pune 411016
> > >  Tel Direct +91 20 66248045 * Main +91 20 66248000 * Fax +91 20 25606222
> > >  yuvraj.shinde@sos.sungard.com * www.sungard.com
> > >
> > >
> > >
> > >
> > > Success is never ending and failure is never final.
> > >
> > >
>

Mime
View raw message