赞
踩
我有这种情况:
从IncomingMessage表中获取(读取和删除)一条记录
>读取记录内容
>在某些表中插入东西
>如果在步骤1-3中发生错误(任何异常),请将错误记录插入到OutgoingMessage表中
>否则,将成功记录插入到OutgoingMessage表中
所以步骤1,2,3,4应该在一个事务中,或者步骤1,2,3,5
我的过程从这里开始(这是一个计划的任务):
public class ReceiveMessagesJob implements ScheduledJob {
// ...
@Override
public void run() {
try {
processMessageMediator.processNextRegistrationMessage();
} catch (Exception e) {
e.printStackTrace();
}
}
// ...
}
我的主要功能(processNextRegistrationMessage)在ProcessMessageMediator中:
public class ProcessMessageMediatorImpl implements ProcessMessageMediator {
// ...
@Override
@Transactional(rollbackFor = { RuntimeException.class, ProcessIncomingMessageException.class })
public void processNextRegistrationMessage() throws ProcessIncomingMessageException {
String refrenceId = null;
MessageTypeEnum registrationMessageType = MessageTypeEnum.REGISTRATION;
try {
String messageContent = incomingMessageService.fetchNextMessageContent(registrationMessageType);
if (messageContent == null) {
return;
}
IncomingXmlModel incomingXmlModel = incomingXmlDeserializer.fromXml(messageContent);
refrenceId = incomingXmlModel.getRefrenceId();
if (!StringUtil.hasText(refrenceId)) {
throw new ProcessIncomingMessageException(
"Can not proceed processing incoming-message. refrence-code field is null.");
}
sqlCommandHandlerService.persist(incomingXmlModel);
} catch (Exception e) {
if (e instanceof ProcessIncomingMessageException) {
throw (ProcessIncomingMessageException) e;
}
e.printStackTrace();
// send error outgoing-message
OutgoingXmlModel outgoingXmlModel = new OutgoingXmlModel(refrenceId,
ProcessResultStateEnum.FAILED.getCode(), e.getMessage());
saveOutgoingMessage(outgoingXmlModel, registrationMessageType);
return;
}
// send success outgoing-message
OutgoingXmlModel outgoingXmlModel = new OutgoingXmlModel(refrenceId, ProcessResultStateEnum.SUCCEED.getCode());
saveOutgoingMessage(outgoingXmlModel, registrationMessageType);
}
private void saveOutgoingMessage(OutgoingXmlModel outgoingXmlModel, MessageTypeEnum messageType)
throws ProcessIncomingMessageException {
String xml = outgoingXmlSerializer.toXml(outgoingXmlModel, messageType);
OutgoingMessageEntity entity = new OutgoingMessageEntity(messageType.getCode(), new Date());
try {
outgoingMessageService.save(entity, xml);
} catch (SaveOutgoingMessageException e) {
throw new ProcessIncomingMessageException("Can not proceed processing incoming-message.", e);
}
}
// ...
}
正如我所说如果在步骤1-3中发生任何异常,我想插入一个错误记录:
catch (Exception e) {
if (e instanceof ProcessIncomingMessageException) {
throw (ProcessIncomingMessageException) e;
}
e.printStackTrace();
//send error outgoing-message
OutgoingXmlModel outgoingXmlModel = new OutgoingXmlModel(refrenceId,ProcessResultStateEnum.FAILED.getCode(), e.getMessage());
saveOutgoingMessage(outgoingXmlModel, registrationMessageType);
return;
}
它是SqlCommandHandlerServiceImpl.persist()方法:
public class SqlCommandHandlerServiceImpl implements SqlCommandHandlerService {
// ...
@Override
@Transactional
public void persist(IncomingXmlModel incomingXmlModel) {
Collections.sort(incomingXmlModel.getTables());
List queries = generateSqlQueries(incomingXmlModel.getTables());
for (ParametricQuery query : queries) {
queryExecuter.executeQuery(query);
}
}
// ...
}
但是当sqlCommandHandlerService.persist()抛出异常(这里是一个org.hibernate.exception.ConstraintViolationException异常)时,在OutgoingMessage表中插入错误记录之后,当事务想提交时,我会收到UnexpectedRollbackException.我不知道我的问题在哪里
Exception in thread "null#0" org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:717)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:394)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)
at ir.tamin.branch.insuranceregistration.services.schedular.ReceiveMessagesJob
at ir.asta.wise.core.util.timer.JobScheduler$ScheduledJobThread.run(JobScheduler.java:132)
我使用hibernate-4.1.0-Final,我的数据库是oracle,而这是我的事务管理器bean:
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
proxy-target-class="true" />
提前致谢.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。