У меня есть база данных с двумя таблицами, accountA и accountB. Я хочу сделать некоторые обновления для обеих этих таблиц базы данных в одной и той же области транзакции, поэтому я использовал компонент, но когда при обновлении учетных записей B происходит исключение, обновления учетных записей A продолжаются, мне нужно, чтобы моя база данных выполняла оба обновления вместе или никто из них.
для проверки правильности работы транзакционного компонента я сделал изменение имени таблицы accountB, возникло исключение. Я ожидал, что обновление таблицы accountA будет остановлено, но этого не произошло. я сделал что-то неправильно?
<bean id = "mysql-ds-local" class = "org.apache.commons.dbcp.BasicDataSource" destroy-method = "close">
<property name = "driverClassName" value = "com.mysql.jdbc.Driver"/>
<property name = "url" value = "jdbc:mysql://localhost:3306/BankDB?relaxAutoCommit=true"/>
<property name = "username" value = "root"/>
<property name = "password" value = "osslab"/>
<property name = "poolPreparedStatements" value = "true"/>
</bean>
<bean id = "txManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name = "dataSource" ref = "mysql-ds-local"/>
</bean>
<camelContext id = "camel-jdbc-test" xmlns = "http://camel.apache.org/schema/blueprint" >
<route id = "main-route-jdbc">
<from uri = "timer://webinar?period=20000" />
<transacted />
<to uri = "direct:reduceCredit"/>
<to uri = "direct:increaseCredit"/>
</route>
<route id = "reduceCredit-route">
<from uri = "direct:reduceCredit"/>
<log message = "in direct accountA"/>
<setBody>
<constant>update accountsA set credit = credit + 1 where id = 1</constant>
</setBody>
<to uri = "jdbc:mysql-ds-local" />
</route>
<route id = "increaseCredit-route">
<from uri = "direct:increaseCredit"/>
<log message = "in direct accountB"/>
<setBody>
<constant>update accountsB set credit = credit + 1 where id = 1</constant>
</setBody>
<to uri = "jdbc:mysql-ds-local" />
</route>
</camelContext>
Возможно, вы просто пропустили это, но ключевой элемент, который отсутствует в вашем вопросе, — это DataSourceTransactionManager
, который делает ваш DataSource
транзакционным.
<bean id = "jdbcTransactionManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name = "dataSource" ref = "myDataSource"/>
</bean>
Есть ли что-то еще, что я забыл добавить?
Почему у вас есть relaxAutoCommit=true
в URL вашей базы данных? Разве это не игнорирование команд транзакций, таких как commit()
или rollback()
, хотя autoCommit
включен?
Я тестировал его без autoCommit, но ничего не изменилось.
Тогда вам, вероятно, придется отлаживать его, чтобы найти проблему. Либо есть недостающая часть, которую мы не находим, и поэтому у вас вообще нет транзакции, либо ваш маршрут работает идеально, но ваша база данных не может выполнять транзакции или откаты.
ваш ответ помог мне, а также я добавляю Required policy в свой план для работы.
спасибо за ваш ответ, вы правы, я добавляю его в свой план, но это еще не решает проблему :(