Ibatis startBatch()仅适用于SqlMapClient自己的启动和提交事务,而不适用于Spring管理的事务

时间:2010-05-27 14:09:55

标签: java mysql spring ibatis

我发现即使我有Spring事务包装的代码,并且它在我期望的时候提交/回滚,为了在使用Ibatis和Spring时使用JDBC批处理我需要使用显式的SqlMapClient事务方法

即。这按照我的期望进行批处理:

dao.getSqlMapClient().startTransaction();
dao.getSqlMapClient().startBatch();

int i = 0;
for (MyObject obj : allObjects)
{
    dao.storeChange(obj);

    i++;
    if (i % DB_BATCH_SIZE == 0)
    {
        dao.getSqlMapClient().executeBatch();
        dao.getSqlMapClient().startBatch();
    }
}

dao.getSqlMapClient().executeBatch();
dao.getSqlMapClient().commitTransaction();

但如果我没有开始和结束事务语句,并依赖Spring来管理事物(这就是我想要做的事情!),批处理就不会发生。

鉴于Spring在交易管理方面似乎处理其讨价还价的方面,有人可以就此处的任何已知问题提出建议吗?

(数据库是MySQL;我知道有关其INSERT语句重写的JDBC伪批处理方法的问题,这绝对不是问题)

1 个答案:

答案 0 :(得分:2)

通过阅读各种资源和反复试验找到了这个背后的原因,我在这里记录了我们的结果,因为它可以帮助其他人。

事实证明,不同的行为是由于我们的DAO类扩展了Spring的SqlMapClientTemplate。在那个班级,你有两个“选择”(我说选择;一个是正确的,一个不是):

  • 直接使用insert(),update()等;一直使用完整的Spring对象

  • getSqlMapClient()。insert(),update()等;这个实际上使用了getSqlMapClient()返回的com.ibatis ...对象,而不是Spring的

一般工作,但从我的阅读中看,第一个选项更好,例如如果你使用Spring,你想要完全基于Spring,而不是“跳出”到Ibatis对象。

现在,SqlMapClientTemplate不直接提供对startBatch()/ executeBatch()的访问,只提供方便的insert(),update()内容,因此这样的代码是必要的。下面的代码完全适用于我们的Spring托管事务,而不是显式代码startTransaction()。

(免责声明由于我的“匿名”工作代码可能包含错误,以便清晰起见)

public class MyFunkyDao extends SqlMapClientDaoSupport
{
    private static final int DB_BATCH_SIZE = 1000;

    public void storeMyData(final List<MyData> listData)
    {
        getSqlMapClientTemplate().execute( new SqlMapClientCallback()
        {
            @Override
            public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException
            {
                int count = 0, total = 0;

                Map<String, Object> params = new HashMap<String, Object>();

                executor.startBatch();

                for (MyData data: listData)
                {
                    params.put("param name 1", data.getValue());

                    executor.insert("insertData", params);

                    count++;
                    if (count % DB_BATCH_SIZE == 0) 
                    {
                        total += executor.executeBatch();
                        executor.startBatch();
                    }

                    params.clear();
                }

                total += executor.executeBatch();

                return new Integer(total);
            }
        });
    }
}

链接:http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/orm/ibatis/SqlMapClientTemplate.html