繁体   English   中英

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

[英]Ibatis startBatch() only works with SqlMapClient's own start and commit transactions, not with Spring-managed ones

我发现即使我的代码被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伪批处理方法有关的问题,这里绝对不是问题)

通过阅读各种资源和反复试验找到了造成这种情况的原因,我在这里记录了我们的结果,因为它可能会帮助其他人。

原来,不同的行为是由于我们的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

原因是。 如果您不进行交易。 iBatis将在调用插入语句后提交事务。 有关更多信息,您可以在com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate中检查代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM