ibatis-user-java mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Albert L Sapp <as...@uiuc.edu>
Subject Re: Proper transaction code pattern
Date Mon, 22 Jan 2007 18:42:22 GMT
We are logging and displaying error reports to the user.  Perhaps that 
is the wrong approach to take, but I just inherited this as the standard 
for coding.  None of the try/catch blocks have a finally clause in 
them.  Instead, they just do a endTransaction in the try part of the 
block and also a endTransaction in each of the catches.  This seems to 
me to be overkill as I would think a finally clause with a 
endTransaction should be sufficient whether a exception is being caught 
and thrown or the transaction was completed successfully with a commit.

Please forgive my terminology if it is wrong.  Even after more than a 
year coding Java, I still am not sure what everything is called.  I 
simply want to make my code as efficient and correct as possible.  My 
thanks to the list for indulging what is probably a simple question.

Thanks,

Al
Clinton Begin wrote:
> If you call startTransaction() you must guarantee that endTransaction
> is called.  The only way to do that is inside a finally block.  You
> really should not need a catch block unless you're logging the
> exception or something.
>
> Cheers,
> Clinton
>
> On 1/22/07, Albert L Sapp <asapp@uiuc.edu> wrote:
>> Clinton,
>>
>> You mentioned one case where I am unclear what I should be doing.  I
>> thought I read the documentation correctly, but still have the
>> question.  We use try/catch extensively in our application.  All the
>> try/catch are coded with a endTransaction prior to the actual throw of
>> the exception and the results of the endTransaction ignored.  Is this
>> really needed?  Can't we just have a endTransaction in a finally
>> clause?  Am I missing something here?  Probably, but I thought I 
>> would ask.
>>
>> Sorry, if it is covered in the docs and missed or didn't understand it.
>>
>> Al
>>
>> Clinton Begin wrote:
>> > 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