看ibatis的官方教程,事务处理 缺省情况下,调用SqlMapClient对象的任意executeXxxx()方法将缺省地自动COMMIT/ROLLBACK。这意味着每次调用executeXxxx()方法都是一个独立的事务。这确实很简单,但对于需要在同一个事务中执行多个语句的情况(即只能同时成功或失败),并不适用。这正是事务处理要关心的事情。 如果您在使用Global Transaction(在SQL Map配置文件中设置),您可以使用自动提交并且可以得到在同一事务中执行的效果。但为了提高性能,最好是明确地划分事务的范围,因为这样做可以减少连接池的通讯流量和数据库连接的初始化。 SqlMapClient对象拥有让您定义事务范围的方法。使用下面SqlMapClient类的方法,可以开始、提交和/或回退事务: public void startTransaction () throws SQLException public void commitTransaction () throws SQLException public void endTransaction () throws SQLException 开始一个事务,意味着您从连接池中得到一个连接,打开它并执行查询和更新SQL操作。使用事务处理的例子如下:
private Reader reader = new Resources.getResourceAsReader( "com/ibatis/example/sqlMapconfig.xml"); private SqlMapClient sqlMap = XmlSqlMapBuilder.buildSqlMap(reader); public updateItemDescription (String itemId, String newDescription) throws SQLException { try { sqlMap.startTransaction (); Item item = (Item) sqlMap.queryForObject ("getItem", itemId); item.setDescription (newDescription); sqlMap.update ("updateItem", item); sqlMap.commitTransaction (); } finally { sqlMap.endTransaction (); } } 注意!事务不能嵌套。在调用commit()或rollback()之前,从同一线程多次调用.startTransaction,将引起抛出例外。换句话说,对于每个SqlMap实例,每个线程最多只能打开一个事务。 注意!SqlMapClient事务处理使用Java的ThreadLocal保存事务对象。这意味着在处理事务时,每个调用startTransaction()的线程,将得到一个唯一的Connection对象。将一个Connection对象返回数据源(或关闭连接)唯一的方法是调用commitTransaction()或rollbackTransaction()方法。否则,会用光连接池中的连接并导致死锁。

解决方案 »

  1.   

    private Reader reader = new Resources.getResourceAsReader( "com/ibatis/example/sqlMapconfig.xml"); private SqlMapClient sqlMap = XmlSqlMapBuilder.buildSqlMap(reader); public updateItemDescription (String itemId, String newDescription) throws SQLException 
    { try 
    { sqlMap.startTransaction ();
      Item item = (Item) sqlMap.queryForObject ("getItem", itemId); 
      item.setDescription (newDescription);
      sqlMap.update ("updateItem", item); 
      sqlMap.commitTransaction (); 
     } finally 
    { sqlMap.endTransaction (); 
     }
     } 注意!事务不能嵌套。在调用commit()或rollback()之前,从同一线程多次调用.startTransaction,将引起抛出例外。换句话说,对于每个SqlMap实例,每个线程最多只能打开一个事务。注意!SqlMapClient事务处理使用Java的ThreadLocal保存事务对象。这意味着在处理事务时,每个调用 startTransaction()的线程,将得到一个唯一的Connection对象。将一个Connection对象返回数据源(或关闭连接)唯一的方法是调用commitTransaction()或rollbackTransaction()方法。
    否则,会用光连接池中的连接并导致死锁。