Как отключить автосохранение в Spring + JDBC?

Я использую Spring с JDBC и обнаружил, что это autocommit.

Как мне настроить, чтобы отключить его в spring -servlet.xml?

Это моя текущая конфигурация:

<bean id="dataSource"
    class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
    p:driverClassName="${jdbc.driverClassName}"
    p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
    p:password="${jdbc.password}" />

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

Ответ 1

Кажется, моя конфигурация пропустила эту строку:

<tx:annotation-driven transaction-manager="txManager"/>

Затем в моих классах обслуживания я использую аннотацию @Transactional. Например

@Service
class CompanyServiceImpl implements CompanyService{
    @Autowired
    private CompanyDAO companyDAO;

    @Transactional
    public void addCompany(Company company) {
            companyDAO.addCompany(company); // in here, there is JDBC sql insert
            companyDAO.addCompany_fail(company); // just for test
    }
}

Если в addCompany_fail() происходит исключение, то первый addCompany() также будет откат.

Я следил за этим документом, чтобы понять, как транзакция контролируется в Spring. http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html

Я выполнил этот документ, чтобы понять, как кодировать JDBC в Spring. http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/jdbc.html

Я также читал это (бесплатно) http://www.infoq.com/news/2009/04/java-transaction-models-strategy. Это действительно хорошо. И я чувствую то же самое с автором, что большинство людей не понимают (или заботятся) о транзакции.

PS: Похоже, что многие люди неправильно понимают, что использование такой инфраструктуры Hibernate/ Spring только для того, чтобы избежать сложности JDBC и управления транзакциями. Многие люди думают, что "JDBC и транзакция настолько сложны, просто используйте Hibernate и забудьте об этих двух". Многие примеры в Интернете о Spring + Hibernate или Spring + JDBC, похоже, вообще не заботятся о транзакции. Я чувствую, что это плохая шутка. Сделка слишком серьезная, просто позволяя чему-то справиться с ней без по-настоящему понимания.

Спящий режим и Spring являются настолько мощными и сложными. Затем, как сказал кто-то: "Великая сила приходит с обязанностями".

ОБНОВЛЕНИЕ: 2013-08-17:. Хороший пример транзакции здесь http://www.byteslounge.com/tutorials/spring-transaction-propagation-tutorial. Однако это не объясняет, что если вы хотите использовать REQUIRES_NEW, почему вам нужно создать другой класс (в противном случае вы получите эту проблему Spring ТРЕБУЕТСЯ ПРОГРАММА ТРАНСПОРТИРОВКИ, REQUIRES_NEW, который, кажется, REQUIRES_NEW действительно не создает новую транзакцию)

Обновление: 2018-01-01: Я создал полный пример с Spring Загрузка 1.5.8.RELEASE здесь https://www.surasint.com/spring-boot-database-transaction-jdbi/ и некоторые основные примеры экспериментов здесь https://www.surasint.com/spring-boot-connection-transaction/

Ответ 2

Попробуйте свойство defaultAutoCommit. Код будет выглядеть так:

<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
p:password="${jdbc.password}"
p:defaultAutoCommit="false" />

Посмотрите на javadoc: http://commons.apache.org/dbcp/apidocs/org/apache/commons/dbcp/BasicDataSource.html#defaultAutoCommit

Ответ 3

Вы не можете, просто запустите свой код в транзакции, Spring автоматически отключит автоматическую фиксацию для вас. Самый простой (по крайней мере, для настройки) способ выполнения фрагмента кода в транзакции в Spring заключается в использовании TransactionTemplate:

TransactionTemplate template = new TransactionTemplate(txManager);

template.execute(new TransactionCallback<Object>() {
  public Object doInTransaction(TransactionStatus transactionStatus) {
    //ALL YOUR CODE ARE BELONG TO... SINGLE TRANSACTION
  }
}