Как использовать одно и то же соединение для двух запросов в Spring?

У меня есть следующий код в дао на основе Spring JdbcTemplate -

getJdbcTemplate().update("Record Insert Query...");
int recordId = getJdbcTemplate().queryForInt("SELECT last_insert_id()");

Проблема в том, что иногда мои запросы на обновление и queryForInt выполняются с использованием разных соединений из пула соединений.

Это приводит к тому, что возвращается неверный идентификатор записи, поскольку предполагается, что MySql last_insert_id() вызывается из того же соединения, которое выдало запрос на вставку.

Я рассматривал вариант SingleConnectionDataSource, но не хочу его использовать, поскольку он снижает производительность приложения. Мне нужно только одно соединение для этих двух запросов. Не для всех запросов для всех услуг.

Итак, у меня есть два вопроса:

  1. Могу ли я управлять соединением, используемым классом шаблона?
  2. Выполняет ли JdbcTemplate автоматическое управление транзакциями? Если я вручную применяю транзакцию к моему методу Dao, означает ли это, что для каждого запроса будут созданы две транзакции?

Надеюсь, вы, ребята, сможете пролить свет на эту тему.

Обновление— я попробовал подход nwinkler и обернул свой сервисный уровень транзакцией. Я был удивлен, увидев, что та же ошибка снова появляется через некоторое время. Копаясь в исходном коде Spring, я нашел это -

public <T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action) 
throws DataAccessException {
//Lots of code  
Connection con = DataSourceUtils.getConnection(getDataSource()); 
//Lots of code 
}

Таким образом, вопреки тому, что я думал, не обязательно одно соединение с базой данных на транзакцию, а одно соединение для каждого выполняемого запроса. Что возвращает меня к моей проблеме. Я хочу выполнить два запроса из одного и того же соединения. :-(

Обновление-

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="${db.driver}" />
        <property name="url" value="${db.jdbc.url}" />
        <property name="username" value="${db.user}" />
        <property name="password" value="${db.password}" />
        <property name="maxActive" value="${db.max.active}" />
        <property name="initialSize" value="20" />
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
        autowire="byName">
        <property name="dataSource">
            <ref local="dataSource" />
        </property>
    </bean>


    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <tx:advice id="transactionAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*" propagation="REQUIRES_NEW" rollback-for="java.lang.Exception" timeout="30" />
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(* service.*.*(..))" />
        <aop:pointcut id="pointcut2" expression="execution(* *.ws.*.*(..))" />

        <aop:advisor pointcut-ref="pointcut" advice-ref="transactionAdvice" />
        <aop:advisor pointcut-ref="pointcut2" advice-ref="transactionAdvice" />
    </aop:config>
6
задан Monika Michael 4 October 2012 в 10:28
поделиться