这是我的问题。
我使用2个EJB / JPA / Hibernate模块处理同步批处理。
第一个模块读取数据库A中的信息并检测更改。
一旦检测到,修改后的项目将通过JMS发送到第二个模块。
第二个模块读取消息并遍历修改后的项目,并更新数据库B中的信息。
一旦更新过程完成,则将包含成功更新的项目的ID的消息发送到第一个模块,该模块在数据库A中标记成功更新的项目。
所有过程都可以正常工作,但是我不知道如何使用容器管理的EntityManager管理在持久性过程中可能发生的异常。
如果我不使用容器管理的EntityManager,则将为每个插入打开一个新事务,然后提交它或回滚它,取决于是否发生任何异常。
我需要知道何时发生异常,以免在列表中成功添加当前正在处理的项目的ID,并导致异常,而列表中的项目ID已成功更新。另外,如果我正在处理10个项目,并且列表中的第一个项目创建了例外,则我需要继续其他9个项目。
我认为在持久方法前面使用@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)可以解决我的问题,但没有解决。
有没有一种方法可以使用容器管理的EntityManager执行我需要做的事情?
谢谢。
最佳答案
通过使用@TransactionManagement(TransactionManagementType.BEAN)作为类的定义。我能够自己管理交易。
@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
public class MyBean implements MyBeanInterface{
@PersistenceContext
private EntityManager em;
@Resource
private UserTransaction userTransaction;
@Override
public List<String> updateItems(List<Items> items) {
List<String> itemsId=new ArrayList<String>();
for(Item item : items){
try{
userTransaction.begin();
doMyStuff(...);
userTransaction.commit();
itemsId.add(item.getId());
}catch(Exception e){
try {
userTransaction.rollback();
} catch (IllegalStateException e1) {
e1.printStackTrace();
} catch (SecurityException e1) {
e1.printStackTrace();
} catch (SystemException e1) {
e1.printStackTrace();
}
}
}
return itemsId;
}
}
它正在工作,但我想知道是否有更清洁的方法?
我的意思是不使用显式的beginTransaction,commitTransaction和rollbackTransaction。
例如,通过在doMyStuff()调用的方法周围使用注释:
谢谢。