Jakarta ee 什么';在EJB中获取多个事务是一种干净、标准的方法吗?
我有一个Jakarta ee 什么';在EJB中获取多个事务是一种干净、标准的方法吗?,jakarta-ee,ejb,bulk,transactional,Jakarta Ee,Ejb,Bulk,Transactional,我有一个batchEdit(List entity)在循环中调用edit(E entity)函数,而每个edit()都有自己的事务,因此失败的编辑不会回滚好的编辑。我目前的实施方式如下: 选项1 @Stateless @TransactionManagement( value = TransactionManagementType.CONTAINER ) public class Service<E> { @Resource private SessionConte
batchEdit(List entity)
在循环中调用edit(E entity)
函数,而每个edit()都有自己的事务,因此失败的编辑不会回滚好的编辑。我目前的实施方式如下:
选项1
@Stateless
@TransactionManagement( value = TransactionManagementType.CONTAINER )
public class Service<E> {
@Resource
private SessionContext context;
@Override
@TransactionAttribute( value = TransactionAttributeType.REQUIRES_NEW )
public E edit( E entity ) {
//edit code
}
@Override
public List<E> bulkEdit( List<E> entities ) {
for(E entity : entities){
//case 1: Regular edit, Does not create a new transaction!
//edit(entity);
//case 2: Hacky edit, creates a new transaction
context.getBusinessObject( Service.class ).editPersistNulls( entity );
}
}
}
但这样我就失去了“JPA魔力”,不得不到处管理交易。我不认为我的团队中的其他人会想经历这种情况,所以如果有更好或标准的方法来做到这一点,任何见解都是值得赞赏的
我们正在使用OpenJPA和ejb,但我们正在努力保持接近JPA标准 我猜“哈奇”在旁观者的眼里<代码>上下文。getBusinessObject的存在正是为了让您可以做这种事情
另一种方法是使用第二类:
@Stateless
public class BulkService<E> {
@EJB
private Service<E> service;
public List<E> bulkEdit( List<E> entities ) {
for(E entity : entities) {
service.editPersistNulls( entity );
}
}
}
@无状态
公共舱位服务{
@EJB
私人服务;
公共列表编辑(列表实体){
对于(E实体:实体){
服务.editPersistNulls(实体);
}
}
}
不过要小心大型实体列表,因为包含的事务可能会超时
如果使用java EE 7兼容的服务器实现,那么考虑使用支持。 您可以在自己中注入EJB。< /P>
@Stateless
public class Service<E> {
@EJB
private Service<E> self;
@TransactionAttribute(REQUIRES_NEW)
public void edit(E entity) {
// ...
}
@TransactionAttribute(NOT_SUPPORTED)
public void bulkEdit(List<E> entities) {
for (E entity : entities) {
self.edit(entity);
}
}
}
它还使原始的
edit()
方法不受潜在的不必要的REQUIRES\u新的
transaction属性的影响,因为它可能会从其他服务调用,当然这些服务应该保留在同一事务中。对于@Asynchronous
来说,每次调用都需要一个新的事务更有意义。很有趣。我们最终使用了getBusinessObject解决方案;唯一令人恼火的是,它需要的是bean的接口,而不是bean的类本身。传递bean的类本身会输出一个“组件没有这样的接口:如果您完全消除了接口,那么您可以使用类名。如果您正在计划一系列不同的实现,那么只在EJB上使用一个接口,这并不常见。我将由我的团队来运行它。我们有可能进行测试的接口,但我们还没有完成,但是传入接口将是一个巨大的重构。当我在短期内调用异步方法两次(甚至更频繁)时,会发生什么。调用是否在溢出发生之前堆叠?最后一个问题。您使用的是必填项。既然调用函数不受支持,那么所需的属性不是相同的吗?@kaiser Nope。它不是在同一个实例上调用的。我想您需要退一步,了解EJB实际上是如何工作的:
@Stateless
public class Service<E> {
@EJB
private Service<E> self;
@TransactionAttribute(REQUIRES_NEW)
public void edit(E entity) {
// ...
}
@TransactionAttribute(NOT_SUPPORTED)
public void bulkEdit(List<E> entities) {
for (E entity : entities) {
self.edit(entity);
}
}
}
@Stateless
public class Service<E> {
@EJB
private Service<E> self;
public void edit(E entity) {
// ...
}
@Asynchronous
@TransactionAttribute(REQUIRES_NEW)
public void asyncEdit(E entity) {
// ...
}
@TransactionAttribute(NOT_SUPPORTED)
public void bulkEdit(List<E> entities) {
for (E entity : entities) {
self.asyncEdit(entity);
}
}
}