2016-05-13 45 views
1

我试图用内Wildfly的MyBatis-CDI和我需要运行在不同的交易方法的一部分,MyBatis的使用REQUIRES_NEW JTA事务类型 - 见下面的代码片段:上Wildfly

@Stateless 
@TransactionManagement(TransactionManagementType.CONTAINER) 
public class ItemService { 

    @Inject 
    @Mapper 
    ItemMapper mapper; 

    @TransactionAttribute(TransactionAttributeType.REQUIRED) 
    public void doSomething() { 
     List<Item> items = mapper.findByTime(new Date()); 
     for(Item i : items) { 
      update(i); 
     } 
    } 

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
    public void update(Item item) { 
     mapper.updateSomehow(item); 
    } 
} 

这是正确的方式如何去做吧?这是由mybatis-cdi支持的,还是应该以不同的方式完成?

回答

1

由于在方法中使用自引用时不适用拦截器,因此您没有得到预期的行为,例如doSomething()如何直接调用update()。你需要在一个单独的bean中发生,以允许单独的事务交互。

+0

感谢,发现它在通过与自己:https://github.com/dlee0113/java_ee_patterns_and_best_practices/blob/master /SelfInvokingEJB/src/java/com/abien/patterns/business/selfinvocation/Hack.java – miran

0

你可以注入你的EJB到自身,以便通过代理来调用它:

@Stateless 
@TransactionManagement(TransactionManagementType.CONTAINER) 
class ItemService { 

    @Inject 
    @Mapper 
    private ItemMapper mapper; 

    @Inject // or @EJB 
    private ItemService itemService; 

    @TransactionAttribute(TransactionAttributeType.REQUIRED) 
    public void doSomething() { 
     List<Item> items = mapper.findByTime(new Date()); 
     for (Item i : items) { 
      itemService.update(i); // here's the trick 
     } 
    } 

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
    public void update(Item item) { 
     mapper.updateSomehow(item); 
    } 
}