Джакартские транзакции
Jakarta Transactions ( JTA ; ранее Java Transaction API ), один из Jakarta EE API , позволяет распределенные транзакции выполнять между несколькими ресурсами X/Open XA в среде Java . JTA — это спецификация, разработанная в рамках процесса сообщества Java под названием JSR 907. JTA обеспечивает:
- демаркация [ нужны разъяснения ] границ транзакции
- X/Open XA API, позволяющий ресурсам участвовать в транзакциях.
Архитектура X/Open XA
[ редактировать ]В архитектуре X/Open XA менеджер транзакций или монитор обработки транзакций (монитор TP) координирует транзакции между несколькими ресурсами, такими как базы данных и очереди сообщений. У каждого ресурса есть свой менеджер ресурсов. Менеджер ресурсов обычно имеет собственный API для управления ресурсом, например API JDBC для работы с реляционными базами данных. Кроме того, менеджер ресурсов позволяет монитору TP координировать распределенную транзакцию между своим собственным и другими менеджерами ресурсов. Наконец, существует приложение, которое взаимодействует с монитором TP, чтобы начать, зафиксировать или откатить транзакции. Приложение также взаимодействует с отдельными ресурсами, используя собственный API для изменения ресурса.
JTA-реализация архитектуры X/Open XA
[ редактировать ]JTA API состоит из классов в двух пакетах Java :
JTA создан на основе архитектуры X/Open XA, но определяет два разных API для разграничения границ транзакций. Он различает сервер приложений, такой как сервер EJB , и компонент приложения. Он обеспечивает интерфейс, javax.transaction.TransactionManager
, который используется самим сервером приложений для запуска, фиксации и отката транзакций. Он обеспечивает другой интерфейс, javax.transaction.UserTransaction
, который используется общим клиентским кодом, таким как сервлет или EJB, для управления транзакциями.
Архитектура JTA требует, чтобы каждый менеджер ресурсов реализовал javax.transaction.xa.XAResource
интерфейс для управления монитором TP. Как указывалось ранее, каждый ресурс будет иметь свой собственный API, например:
- реляционные базы данных используют JDBC
- службы обмена сообщениями используют JMS
- обобщенные EIS ( Информационная система предприятия ) ресурсы [ нужны разъяснения ] используйте API соединителя Java EE .
Интерфейс прикладного программирования
[ редактировать ]API Jakarta Transactions состоит из трех элементов: интерфейса разграничения транзакций приложений высокого уровня, интерфейса менеджера транзакций высокого уровня, предназначенного для сервера приложений, и стандартного Java-сопоставления протокола X/Open XA, предназначенного для менеджера транзакционных ресурсов.
Пользовательский интерфейс транзакции
[ редактировать ]The javax.transaction.UserTransaction
интерфейс предоставляет приложению
возможность программного контроля границ транзакций. Этот интерфейс можно использовать
клиентскими программами Java или EJB-компонентами.
The UserTransaction.begin()
метод запускает глобальную транзакцию и связывает
транзакция с вызывающим потоком. Ассоциация транзакций с потоками управляется
прозрачно менеджером транзакций.
Поддержка вложенных транзакций не требуется. Метод UserTransaction.begin выдает исключение NotSupportedException, когда вызывающий поток уже связан с транзакцией, а реализация менеджера транзакций не поддерживает вложенные транзакции.
Распространение контекста транзакции между прикладными программами обеспечивается базовые реализации менеджера транзакций на клиентских и серверных машинах. Формат контекста транзакции, используемый для распространения, зависит от протокола и должен быть согласовывается между хостами клиента и сервера. Например, если менеджер транзакций является реализацией спецификации JTS , она будет использовать контекст транзакции формат распространения, указанный в спецификации CORBA OTS 1.1. Сделка распространение прозрачно для прикладных программ.
@Транзакционная аннотация
[ редактировать ]The javax.transaction.Transactional
аннотация предоставляет приложению
возможность декларативно контролировать границы транзакций. Эту аннотацию можно применить к любому классу, указанному в спецификации Jakarta EE.
определяется как управляемый компонент (который включает управляемые компоненты CDI).
Пример кода ниже иллюстрирует использование @Transactional
в управляемом компоненте CDI с областью запроса:
@RequestScoped
public class ExampleBean {
@Transactional
public void foo() { // A transaction is active here
// Do work
} // After the method returns transaction is committed or rolled back
}
Транзакционное поведение можно настроить с помощью атрибута в аннотации. Доступные параметры во многом соответствуют параметрам спецификации EJB .
Аннотация @TransactionScoped
[ редактировать ]The javax.transaction.TransactionScoped
аннотация предоставляет приложению
возможность объявить, что область действия компонента привязана ко времени активности данной транзакции.
Пример кода ниже иллюстрирует использование @TransactionScoped
в управляемом компоненте CDI с областью запроса:
@TransactionScoped
public class TxScopedBean {
public int number;
public int getNumber() {return number;}
public void setNumber(int number) {this.number = number;}
}
@RequestScoped
public class ExampleBean {
@Inject
private TxScopedBean txScopedBean;
@Transactional
public void foo() {
txScopedBean.setNumber(1);
}
@Transactional
public void bar() {
System.out.print(tXscopedBean.getNumber());
}
}
Если метод foo() сначала вызывается для управляемого экземпляра exampleBean, а затем вызывается метод bar() , напечатанное число будет 0, а не 1. Это связано с тем, что каждый метод имеет свою собственную транзакцию и, следовательно, свой собственный экземпляр TxScopedBean. . Таким образом, число 1, которое было установлено во время вызова foo(), не будет видно во время вызова bar() .
Поддержка UserTransaction на сервере EJB
[ редактировать ]Серверы EJB необходимы для поддержки UserTransaction
интерфейс для использования EJB
bean-компоненты со значением BEAN в javax.ejb.TransactionManagement
аннотация (это называется транзакциями, управляемыми компонентами или BMT). UserTransaction
Интерфейс доступен компонентам EJB либо через EJBContext
интерфейс с использованием
getUserTransaction
метод или непосредственно путем инъекции с использованием общего @Resource
аннотация. Таким образом, приложение EJB не взаимодействует с
Менеджер транзакций непосредственно для разграничения транзакций; вместо этого EJB-компонент полагается
на сервере EJB для обеспечения поддержки всех его транзакций, как определено в
Спецификация Jakarta Enterprise Beans. (Основное взаимодействие между EJB
Сервер и TM прозрачны для приложения; бремя реализации управления транзакциями лежит на поставщике контейнеров и серверов EJB. [ 1 ] )
Пример кода ниже иллюстрирует использование UserTransaction
через транзакции, управляемые компонентом, в сессионном компоненте EJB:
@Stateless
@TransactionManagement(BEAN)
public class ExampleBean {
@Resource
private UserTransaction utx;
public void foo() {
// start a transaction
utx.begin();
// Do work
// Commit it
utx.commit();
}
}
Альтернативно, UserTransaction
можно получить из SessionContext
:
@Stateless
@TransactionManagement(BEAN)
public class ExampleBean {
@Resource
private SessionContext ctx;
public void foo() {
UserTransaction utx = ctx.getUserTransaction();
// start a transaction
utx.begin();
// Do work
// Commit it
utx.commit();
}
}
Однако обратите внимание, что в приведенном выше примере, если @TransactionManagement(BEAN)
аннотация опущена, транзакция JTA запускается автоматически всякий раз, когда foo()
вызывается и автоматически фиксируется или откатывается, когда foo()
выходит. Используя UserTransaction
таким образом, в EJB-программировании нет необходимости, но может потребоваться для очень специализированного кода.
Поддержка UserTransaction в JNDI
[ редактировать ]UserTransaction должен быть доступен в разделе java:comp/UserTransaction
(если в среде установлена реализация JTA).