2016-05-13 76 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); 
    } 
}