я писал упомянутый пользовательский исходящий адаптер канала, который использует пружинный JDBC пакетное способность:
public class ArrayListSqlBatchOBCA {
private final static Logger log = LoggerFactory.getLogger(ArrayListSqlBatchOBCA.class);
private NamedParameterJdbcTemplate template;
private String sql;
public void process(Message<? extends ArrayList<?>> message) throws Exception {
try {
ArrayList<?> list = (ArrayList<?>) message.getPayload();
SqlParameterSource[] batchArgs = new SqlParameterSource[list.size()];
for (int i = 0; i < list.size(); i++) {
batchArgs[i] = new BeanPropertySqlParameterSource(list.get(i));
}
template.batchUpdate(sql, batchArgs);
}
catch (Exception e) {
log.error("Exception while processing message", e);
throw e;
}
}
}
Это, как я использую его (XML конфигурации):
<channel id="cc"/>
<outbound-channel-adapter channel="cc" method="process">
<beans:bean class="mypackage.ArrayListSqlBatchOBCA">
<beans:property name="template" ref="jdbcTemplate"/>
<beans:property name="sql"
value="INSERT INTO test (field1,field2,field3)
VALUES (:f1,:f2,:f3)"/>
</beans:bean>
</outbound-channel-adapter>
Кроме того, я добавил ?reWriteBatchedInserts=true
в URL-адрес jdbc моего источника данных (я использую драйвер JDBC postgres).
Documentation about the option:
reWriteBatchedInserts - Включить оптимизацию переписать и разрушаться совместимые заявления INSERT, которые дозируют. Если включено, pgjdbc перезаписывает пакет insert into ... values(?, ?)
в insert into ... values(?, ?), (?, ?), ...
Таким образом, используя небольшой пользовательский код, я вставляю сразу несколько строк из коллекции ввода.
Я не знаю, каков ваш критерий измерения, но вот несколько советов: (1) НЕ ВСТАВЛЯЙТЕ один за раз; пакетные запросы для сокращения сетевого трафика, (2) Разделите список на более мелкие фрагменты, которые вы фиксируете как единицу работы, чтобы вы не создали огромный сегмент отката, (3) Посмотрите, ускоряет ли параллельные потоки Java 8 , – duffymo
Какой вкус SQL вы используете? Вероятно, вам придется получить довольно низкий уровень, если вы вставляете 500K в режиме реального времени. Например, MySQL имеет вызов LOAD INTO, который принимает входной поток, который намного быстрее, чем стандартная вставка пакета. –
Прямо сейчас, Spring Integration не поддерживает эту функцию. Для этого есть запрос функции - https://jira.spring.io/browse/INT-3364. Итак, для этой цели я использую самозаписывающийся адаптер исходящего канала. – Eugene