#spring #postgresql #jdbctemplate #spring-jdbc
#spring #postgresql #jdbctemplate #spring-jdbc
Вопрос:
Я использую шаблон Spring JDBC вместе с PostgreSQL. Ниже приведен мой источник данных конфигурации и параметры транзакции:
<bean id="databasePropertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/config/database.properties" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="${database.driverClassName}"
p:url="${database.url}"
p:username="${database.username}"
p:password="${database.password}" />
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="txManager" />
На моем бизнес-уровне я делаю следующее:
@Transactional(rollbackFor=Exception.class)
@RequiresPermissions("hc:patient_createInvoice")
public Long createInvoice(Invoice invoice, List<InvoiceItem> items) throws ValidationException, NetAmountMismatchException, PatientInvoiceException
{
try{
dao1.insert(invoice);
}
catch(DataAccessException x){
throw new PatientInvoiceException(x);
}
try{
somevalidation(invoiceItem); // Causes validation exception
dao2.insert(invoiceItems);
}
catch(DataAccessException x){
throw new PatientInvoiceException(x);
}
}
Что-то вроде этого. Что мне нужно, так это то, что всякий раз, когда какое-либо исключение (проверенное или непроверенное) выбрасывается из этого метода, все выполненные до сих пор обновления БД должны быть отменены.
Этого не происходит с текущим кодом.
Чего мне не хватает на самом деле?
Ответ №1:
По умолчанию Spring откатывает транзакции только для непроверенных исключений. Из справочного руководства Spring:
Код инфраструктуры транзакций Spring Framework помечает транзакцию для отката только в случае непроверенных исключений во время выполнения; […] Проверенные исключения, которые генерируются из транзакционного метода, не приводят к откату в конфигурации по умолчанию.
Однако вы можете настроить Spring для отката и для проверенных исключений, например:
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="*" rollback-for="ValidationException, NetAmountMismatchException, PatientInvoiceException" />
</tx:attributes>
</tx:advice>
Комментарии:
1. Извиняюсь, немного опоздал с ответом. В этом случае, что именно использовать @Transactional(rollbackFor=Exception.class ) ? Я понимаю, что если я дам rollbackFor=Exception.class Исключение и подклассы будут кандидатами на откат.
2. Извините, я пропустил это. Вы правы,
rollbackFor
по сути, это аннотированный эквивалент того,rollback-for
который я использовал в своем объявлении XML, подробности см. в справочных документах .3. Точно. Но, используя вышеупомянутый код, транзакция не откатывалась. он частично зафиксирован в базе данных. Все классы исключений, упомянутые выше, были получены из RuntimeException. Есть идеи? Мне все еще нужно выполнять операции AOP?