Как я могу настроить отключение автоматической фиксации в Spring + JDBC? - PullRequest
13 голосов
/ 10 марта 2012

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

Как настроить, чтобы отключить его в 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>

Ответы [ 3 ]

14 голосов
/ 15 марта 2012

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

<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 и Transaction Control. Многие люди думают, что «JDBC и Transaction настолько сложны, просто используйте Hibernate и забудьте об этих двух». Многие примеры в Интернете о Spring + Hibernate или Spring + JDBC, похоже, вообще не заботятся о транзакциях. Я чувствую, что это плохая шутка. Транзакция слишком серьезна, чтобы позволить чему-то справиться с ней, не понимая по-настоящему.

Hibernate и Spring такие мощные и такие сложные. Затем, как кто-то сказал: «Великая сила приходит с обязанностями».

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

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

6 голосов
/ 10 марта 2012

Попробуйте свойство 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

2 голосов
/ 10 марта 2012

Вы не можете просто запустить свой код в транзакции, 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
  }
}
...