5.4.5.1. Программное управление транзакциями
Программное управление транзакциями осуществляется с помощью интерфейса com.haulmont.cuba.core.Transaction
, ссылку на который можно получить методами createTransaction()
или getTransaction()
интерфейса инфраструктуры Persistence.
Метод createTransaction()
создает новую транзакцию и возвращает интерфейс Transaction
. Последующие вызовы методов commit()
, commitRetaining()
, end()
этого интерфейса управляют созданной транзакцией. Если в момент создания существовала другая транзакция, то она будет приостановлена, и возобновлена после завершения созданной.
Метод getTransaction()
вызывает либо создание новой, либо присоединение к текущей транзакции. Если в момент вызова существовала активная транзакция, то метод успешно завершается, и последующие вызовы commit()
, commitRetaining()
, end()
не оказывают никакого влияния на существующую транзакцию. Однако если end()
вызван без предварительного вызова commit()
, то текущая транзакция помечается как RollbackOnly
.
Примеры программного управления транзакцией:
@Inject
private Metadata metadata;
@Inject
private Persistence persistence;
...
// try-with-resources style
try (Transaction tx = persistence.createTransaction()) {
Customer customer = metadata.create(Customer.class);
customer.setName("John Smith");
persistence.getEntityManager().persist(customer);
tx.commit();
}
// plain style
Transaction tx = persistence.createTransaction();
try {
Customer customer = metadata.create(Customer.class);
customer.setName("John Smith");
persistence.getEntityManager().persist(customer);
tx.commit();
} finally {
tx.end();
}
Интерфейс Transaction имеет также метод execute()
, принимающий на вход класс-действие или lambda-выражение, которое нужно выполнить в данной транзакции. Это позволяет организовать управление транзакциями в функциональном стиле, например:
UUID customerId = persistence.createTransaction().execute((EntityManager em) -> {
Customer customer = metadata.create(Customer.class);
customer.setName("ABC");
em.persist(customer);
return customer.getId();
});
Customer customer = persistence.createTransaction().execute(em ->
em.find(Customer.class, customerId, "_local"));
Следует иметь в виду, что метод execute()
у некоторого экземпляра Transaction
можно вызвать только один раз, так как после выполнения кода действия транзакция завершается.