It sounds like you've done a good job recognizing the problem. You're right that it would be better to put it in the try/finally block, especially if the code is catching a specific exception (like SQLException). Think about what happens if an unexpected RuntimeException is thrown...
You're on the right track. Cheers, ;-) Clinton On 1/22/07, Albert L Sapp <[EMAIL PROTECTED]> wrote:
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 <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> 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:[EMAIL PROTECTED] >> >> > 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" <[EMAIL PROTECTED]> >> >> > 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 <[EMAIL PROTECTED]> 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 >> >> > > [EMAIL PROTECTED] * www.sungard.com >> >> > > >> >> > > >> >> > > >> >> > > >> >> > > Success is never ending and failure is never final. >> >> > > >> >> > > >> >> >> > >> >> >