`
zhangzuanqian
  • 浏览: 270021 次
  • 来自: ...
社区版块
存档分类
最新评论

Proper Ibatis transaction code pattern

阅读更多

copy from http://www.goldenbug.net/2009/06/03/proper-ibatis-transaction-code-pattern/

 

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

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics