Менеджеры ресурсов, такие как реляционные базы данных, предоставляют менеджер транзакций и API для управления транзакциями. Те, кто знаком с JDBC, знают, что по умолчанию транзакция запускается из-за параметра autocommit = true. Каждый оператор, который изменяет базу данных, автоматически фиксируется. Это поведение можно изменить, установив autocommit в false. Теперь программист должен явно начать транзакцию, а затем зафиксировать или откатить транзакцию.
Транзакции, которые имеют дело только с одним ресурсом, таким как одна база данных, называются локальными транзакциями. Транзакции, которые охватывают несколько ресурсов, таких как несколько баз данных или база данных и механизм обмена сообщениями, называются глобальными транзакциями. Глобальные транзакции реализуются с использованием протокола XA, который включает в себя двухфазную фиксацию. Спецификация JTA описывает Java API для программистов для работы с глобальными транзакциями. Методы транзакций в JDBC, такие как begin, commit, rollback, работают только с JDBC и реляционными базами данных, где JTA может работать с любым транзакционным ресурсом.
Однако код, используемый для работы с транзакциями, представляет собой код платформы, который может обрабатываться средой. В начале метода вам нужно начать транзакцию, а когда метод завершится, вам нужно либо зафиксировать, либо откатить транзакцию. Если вы работали с EJB, вам может быть известно, что вы можете указать в дескрипторе развертывания транзакционную среду, в которой должен выполняться метод. Например, вы можете сказать «Требуется новый», что означает начать новую транзакцию перед вызовом метода. Контейнер начинает новую транзакцию до вызова метода и фиксирует ее, когда метод возвращается. Программисту не нужно писать какой-либо Java-код для обработки транзакции.
В оставшейся части статьи мы обсудим пример декларативного управления транзакциями с помощью Spring.
Для этого урока вам понадобятся:
(1) Весна 3.0
(2) Затмение не является обязательным. Я использую затмение в качестве моей IDE. Eclipse позволяет вам экспортировать войну, которую можно развернуть в Tomcat. Но вы также можете использовать другие IDE или инструменты командной строки.
(3) Вы можете скачать исходный код для этого примера по адресу springjdbcwithTransaction.zip .
Мы повторно используем пример из JDBC с блогом Spring, который мы написали некоторое время назад. Давайте добавим поддержку транзакций в MemberSpringJDBCDAO. Этот класс имеет метод insertMember, который вставляет член в базу данных. Давайте немного изменим метод, чтобы выбрасывать RuntimeException после вставки в базу данных. Добавлено исключение времени выполнения, чтобы сделать вид, что произошла ошибка в бизнес-логике при обновлении базы данных.
01
02
03
04
05
06
07
08
09
10
11
|
public int insertMember(Member member) { JdbcTemplate jt = getJdbcTemplate() ; Object[] params = new Object[{member.getFirstname(), member.getLastname(), member.getStreet(),member.getCity(), member.getZip(),member.getEmail(),member.getPassword()} ; int ret = jt.update(insert_sql, params) ; throw new RuntimeException("simulate Error condition') ; return ret ; } |
В этом методе вы ожидаете, что вставка будет зафиксирована в базе данных? Ответ Да, хотя это не желательное поведение. Поведение JDBC по умолчанию — autocommit = true, что означает, что каждая вставка или обновление фиксируются немедленно. Вы можете установить autocommit = false и явно зафиксировать или откатить в конце метода. Но намного легче позволить вашему контейнеру справиться с этим.
Чтобы добавить декларативное управление транзакциями к вышеуказанному методу, выполните следующие действия:
Шаг 1. Определите менеджер транзакций в springjdbcdao.xml
1
2
|
< bean id = "txManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager" /> |
Spring работает с менеджером транзакций для начала и завершения транзакций.
Шаг 2. Включите поддержку аннотаций транзакций.
Добавить в springjdbcdao.xml
1
|
< tx:annotation-driven transaction-manager = "txManager" /> |
Шаг 3. Добавьте аннотацию @Transactional в метод insertMember.
1
2
3
|
@Transactional public int insertMember(Member member) { ... |
@Transactional может принимать свойства, но мы будем использовать значения по умолчанию:
Распространение: обязательно
Обязательно означает, что требуется транзакция. Если транзакции нет, Spring запрашивает у менеджера транзакций ее запуск. Другими возможными значениями является Requ_New, который указывает менеджеру транзакций всегда приостанавливать существующую транзакцию и начинать новую.
Уровень изоляции: по умолчанию
Используйте уровень изоляции по умолчанию для основного менеджера ресурсов.
Откат: Любое исключение во время выполнения вызывает откат
Шаг 4. Запустите обновленный метод insertMember, используя тест Junit MemberSpringJDBCDAOTest.
Вы увидите следующие журналы от менеджера транзакций, указывающие на откат транзакции.
org.springframework.jdbc.datasource.DataSourceTransactionManager — Инициирование отката транзакции
2501 [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager — Инициирование отката транзакции
2501 [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager — откат транзакции JDBC для соединения [org.apache.derby.impl.jdbc.EmbedConnection40@13320911 (XID = 2827), (SESSIONID = 1), (DAT c: \ manoj \ mjprojects \ database \ pumausers), (DRDAID = null)] 2501 [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager — откат транзакции JDBC для соединения [org.apache.derby.impl.jdbc. EmbedConnection40 @ 13320911 (XID = 2827), (SESSIONID = 1), (DATABASE = c: \ manoj \ mjprojects \ database \ pumausers), (DRDAID = null)] 2511
Используйте SQL для проверки таблицы базы данных. Убедитесь, что запись не добавлена.
Шаг 5: Удалите исключение runtimeexception из метода insertMember и снова запустите тест.
Журнал отладки Spring показывает, что транзакция зафиксирована. Используйте SQL для проверки таблицы базы данных. Убедитесь, что запись добавлена в таблицу.
Таким образом, транзакции необходимы для поддержки свойств ACID для источников данных. Декларативные транзакции с использованием Spring облегчают эту задачу.
Ссылка: Весенние и декларативные сделки от нашего партнера JCG Маноя в отчете Хангаонкар .
Статьи по Теме :