我正在使用Spring 4.1.x APIs
,Spring Integration 4.1.x APIs
和Spring Integration Java DSL 1.0.x APIs
进行EIP流,我们使用JdbcPollingChannelAdpater
作为流入口,从Oracle数据库表中使用消息
即使我们在ErrorHandler
的{{1}}上配置了JdbcPollingChannelAdapter
,我们也看到会话的Poller
仍在回滚,而在Transaction
时未提交{1}}抛出并正确处理{1}}。
在阅读完这个帖子:Spring Transactions - Prevent rollback after unchecked exceptions (RuntimeException)之后,我感觉不可能阻止回滚而是强制提交。它是否正确?并且,如果有一种方法,在安全处理错误时,最简单的方法是强制提交而不是回滚?
当前配置:
IntegrationConfig.java:
RuntimeException
ErrorHandler.java
ErrorHandler
--- EDITED包括ExpressionEvaluatingRequestHandlerAdvice Bean ---
@Bean
public MessageSource<Object> jdbcMessageSource() {
JdbcPollingChannelAdapter adapter = new JdbcPollingChannelAdapter(
dataSource,
"select * from SERVICE_TABLE where rownum <= 10 for update skip locked");
adapter.setUpdateSql("delete from SERVICE_TABLE where SERVICE_MESSAGE_ID in (:id)");
adapter.setRowMapper(serviceMessageRowMapper);
adapter.setMaxRowsPerPoll(1);
adapter.setUpdatePerRow(true);
return adapter;
}
@SuppressWarnings("unchecked")
@Bean
public IntegrationFlow inFlow() {
return IntegrationFlows
.from(jdbcMessageSource(),
c -> {
c.poller(Pollers.fixedRate(100)
.maxMessagesPerPoll(10)
.transactional(transactionManager)
.errorHandler(errorHandler));
})
.channel(inProcessCh()).get();
}
---编辑显示虚拟测试消息处理程序---
@Component
public class ErrorHandler implements org.springframework.util.ErrorHandler {
@Autowired
private PlatformTransactionManager transactionManager;
private static final Logger logger = LogManager.getLogger();
@Override
public void handleError(Throwable t) {
logger.trace("handling error:{}", t.getMessage(), t);
// handle error code here...
// we want to force commit the transaction here?
TransactionStatus txStatus = transactionManager.getTransaction(null);
transactionManager.commit(txStatus);
}
}
--- EDITED显示ExecutorChannelInterceptor方法---
@Bean
public Advice expressionEvaluatingRequestHandlerAdvice() {
ExpressionEvaluatingRequestHandlerAdvice expressionEvaluatingRequestHandlerAdvice = new ExpressionEvaluatingRequestHandlerAdvice();
expressionEvaluatingRequestHandlerAdvice.setTrapException(true);
expressionEvaluatingRequestHandlerAdvice.setOnSuccessExpression("payload");
expressionEvaluatingRequestHandlerAdvice
.setOnFailureExpression("payload");
expressionEvaluatingRequestHandlerAdvice.setFailureChannel(errorCh());
return expressionEvaluatingRequestHandlerAdvice;
}
答案 0 :(得分:1)
仅仅因为您的import Foundation
import CoreData
@objc(Dog)
class Dog: NSManagedObject {
// Insert code here to add functionality to your managed object subclass
}
在TX结束后已经正常工作而无效。
以下是几行源代码(ErrorHandler
):
AbstractPollingEndpoint.Poller
其中:
@Override
public void run() {
taskExecutor.execute(new Runnable() {
@Override
public void run() {
.............
try {
if (!pollingTask.call()) {
break;
}
count++;
}
catch (Exception e) {
....
}
}
}
});
}
默认适用于ErrorHandler
(taskExecutor
)。
SyncTaskExecutor
作为TransactionInterceptor
被应用于Aspect
周围的代理。
因此TX在pollingTask
附近完成并熄灭。只有在此之后,pollingTask.call()
开始在ErrorHandler
内工作。
要解决您的问题,您需要确定哪个下游流程部分对于TX rallback不是那么重要,并使某些taskExecutor.execute()
或使用try...catch
来“掩盖”{{1} }。
但正如你已经注意到我必须在 TX内完成