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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值