Ibatis startBatch () работает только с собственными транзакциями запуска и принятия SqlMapClient, а не с управляемыми Spring - PullRequest
4 голосов
/ 27 мая 2010

Я обнаружил, что, хотя у меня есть код, обернутый транзакциями Spring, и он фиксирует / откатывает, когда я ожидал, чтобы использовать пакетную обработку JDBC при использовании Ibatis и Spring, мне нужно использовать явные методы транзакции 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; я знаю о проблемах, связанных с ее псевдопакетным подходом JDBC с перезаписью операторов INSERT, здесь это определенно не проблема)

Ответы [ 2 ]

2 голосов
/ 31 мая 2010

Выяснив причину этого, прочитав различные ресурсы, методом проб и ошибок, я записал наши результаты здесь, поскольку это может помочь кому-то еще.

Оказывается, что различные варианты поведения были связаны с нашими классами DAO, расширяющими Spring SqlMapClientTemplate. В этом классе у вас есть два «выбора» (я говорю «выбор; один правильный, другой на самом деле нет»):

  • прямое использование insert (), update () и т.д .; полное использование объектов Spring

  • getSqlMapClient (). Insert (), update () и т. Д .; на самом деле этот работает с использованием объекта com.ibatis ..., возвращаемого getSqlMapClient (), а не Spring *

Оба обычно работают , но из моего прочтения первый вариант лучше, например. если вы используете Spring, вы хотите быть полностью основанными на Spring, а не «выпрыгивать» на объекты Ibatis.

Теперь SqlMapClientTemplate не предоставляет доступ к startBatch () / executeBatch () напрямую, только удобный метод вставки (), 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

0 голосов
/ 12 мая 2017

Причина в том. Если вы не открываете транзакцию. iBatis выполнит транзакцию после вызова оператора вставки. Для получения дополнительной информации вы можете проверить код в com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...