3.4.5.1. 编程式事务管理
编程式事务管理使用 com.haulmont.cuba.core.Transaction 接口完成。可以通过Persistence基础接口的 createTransaction() 或 getTransaction() 方法获得对它的引用。
createTransaction() 方法创建一个新事务并返回 Transaction 接口。后续调用此接口的 commit() 、 commitRetaining() 、 end() 方法控制创建的事务。如果在创建时有另一个活动的事务,它将先暂停并在新创建的事务完成后恢复。
getTransaction() 方法要么创建新事务,要么附加到已有事务并返回一个嵌套事务。如果在调用时有一个活动的当前事务,那么该方法会成功完成,但后续调用嵌套事务的 commit()、 commitRetaining() 、 end() 方法对当前事务没有影响。但是,在没有调用嵌套事务的 commit() 方法的情况下调用 end() 方法,会将当前事务标记为 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() 方法接受 action 类或 lambda 表达式。action 类或 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"));
需要注意,给定 Transaction 实例的 execute() 方法只能调用一次,因为事务在执行完操作代码后结束。