Установите другой тип ExecutorType для определенного сопоставителя mybatis-spring

1

У меня проблема с использованием mappers в mybatis-spring. (Spring Batch) Мне нужно использовать SqlSessionTemplate с ExecutorType в режиме BATCH для проблем с производительностью (моя программа должна выполнять тысячи операторов insert в таблице). Однако в моей программе мне нужно регистрировать ошибки и обновлять состояния в другой таблице базы данных, и если что-то пойдет не так, при выполнении текущего шага все откаты, включили журналы, что не является приемлемым поведением. Я думал, что могу просто установить два разных SqlSessionTemplate с разными ExecutorType, но если на моем шаге я использую два mappers с разными шаблонами, я получаю исключение, которое говорит, что я не могу изменить ExecutorType во время транзакции, но я не знаю, как решить Эта проблема. Любая помощь приветствуется. Вот некоторая конфигурация XML.

<!-- connect to database -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
    <property name="targetDataSource">
        <ref local="mainDataSource" />
    </property>
</bean> 


<bean id="mainDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" >
    <property name="driverClassName" value="${db.driver}" />
    <property name="url" value="${db.url}" />
    <property name="username" value="${db.user}" />
    <property name="password" value="${db.pass}" />
</bean>

<bean id="infrastructureSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="mapperLocations"
        value="classpath*:com/generali/danni/sipo/mdv/dao/mybatis/*Mapper*.xml" />
    <property name="configLocation" value="classpath:mybatis-config.xml" />
</bean>

<bean id="infrastructureSqlSessionTemplateBatch" class="org.mybatis.spring.SqlSessionTemplate">
    <constructor-arg index="0" ref="infrastructureSqlSessionFactory" />
    <constructor-arg index="1" value="BATCH" />
</bean>

<bean id="infrastructureSqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
    <constructor-arg index="0" ref="infrastructureSqlSessionFactory" />
</bean>

    <bean id="infrastructureAbstractMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"
    abstract="true">
    <property name="sqlSessionTemplate" ref="infrastructureSqlSessionTemplate" /> 
</bean> 

<bean id="infrastructureAbstractMapperBatch" class="org.mybatis.spring.mapper.MapperFactoryBean"
    abstract="true">
    <property name="sqlSessionTemplate" ref="infrastructureSqlSessionTemplateBatch" />
</bean> 

<bean id="erroriMapper" parent="infrastructureAbstractMapper">
    <property name="mapperInterface"
        value="com.mdv.dao.ErroriMapper" />
</bean>

<bean id="stagingFileMapper" parent="infrastructureAbstractMapperBatch">
    <property name="mapperInterface"
        value="com.mdv.dao.StagingFileMapper" />
</bean>

Здесь у меня два картографа, один из которых я хотел бы использовать в режиме BATCH, а другой - в режиме SIMPLE. Как я могу выполнить эту задачу? Каждое предложение приветствуется. Спасибо заранее, и извините за мой плохой английский.

Теги:
spring
spring-batch
mybatis

1 ответ

3
Лучший ответ

После многих попыток я решил изменить свой подход к решению этой проблемы. Я программным образом определил новый SqlSessionFactory, создав новый SqlSession с помощью Batch Executor, и я использовал его. Поскольку это совершенно другой SqlSessionFactory, кажется, что это не дает проблемы, если я использую 2 разных ExecutorType. Здесь пример рабочего кода:

Environment environment = new Environment("TEST", new JdbcTransactionFactory(), dataSource);
        Configuration configuration = new Configuration(environment);
        configuration.addMappers("com.mdv.dao");

        SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(configuration);
        SqlSession sqlSession = ssf.openSession(ExecutorType.BATCH);
        try {

            StagingFileMapper sfm = sqlSession.getMapper(StagingFileMapper.class);
            for(Record r : staging){
                StagingFile sf = new StagingFile();
                //set your sf fields
                sfm.insert(sf);
            }
            sqlSession.commit();
        } catch (Exception e) {
            //manage exception
        }
        finally{
            sqlSession.close();
        }

Ещё вопросы

Сообщество Overcoder
Наверх
Меню