这是我的问题。我使用两个EJB/JPA/Hibernate模块处理同步批处理。
第一个模块读取数据库A中的信息并检测更改。一旦检测到,修改后的项将通过JMS发送到第二个模块。
第二个模块读取消息并遍历修改后的项,并更新数据库B中的信息。
一旦更新过程完成,包含成功更新的项的ID的消息将发送给数据库A中标记成功更新的项的第一个模块。
所有流程都能工作,但我不知道如何使用容器管理的EntityManager来管理持久化过程中可能出现的异常。
如果我没有使用容器管理的EntityManager,我将为每个插入打开一个新事务并提交它或回滚,这取决于是否发生任何异常。
我需要知道何时发生异常,以便不添加当前正在处理的项的id,并在列表中导致异常,并成功地更新项的id。另外,如果我正在处理10个项,并且列表中的第一个项创建了一个异常,则需要继续处理其他9个项。
我认为在持久化方法面前使用@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)可以解决我的问题,但事实并非如此。
是否有一种方法可以使用容器管理的EntityManager?来完成我需要做的事情?
谢谢。
发布于 2012-03-22 00:18:49
通过使用@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()调用的方法周围使用注释:
谢谢。
发布于 2012-03-24 11:03:58
您不需要每次创建新事务。每当您想回滚一个事务时,您都可以选择回滚事务--三级(1) 使用SetRollbackOnly 2) 用ApplicationException标记异常 3)抛出运行时(不应该使用)
https://stackoverflow.com/questions/9799895
复制相似问题