我尝试将TaskExecutor(ThreadPoolTaskExecutor)用于当前运行良好的事务服务,但是当我启动任务时,不再找到现有的事务。
(当低于start()方法时,已经有一个事务处于活动状态) (SimplePOJO不在上下文中,只保留一些数据,可以说存储在数据库中)
@Component
@Transactional(rollbackFor = { Exception.class })
public class MyService {
@Autowired
MyTaskRunner myTaskRunner;
public void start() {
// TransactionSynchronizationManager.isActualTransactionActive() -> true
SimplePOJO pojo = new SimplePOJO();
myTaskRunner.executeTask(pojo);
}
}
Above Service使用此组件:
@Component
public class MyTaskRunner implements ApplicationContextAware {
@Autowired
private TaskExecutor taskExecutor;
private static ApplicationContext applicationContext = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
MyTaskRunner.applicationContext = applicationContext;
}
public void executeTask(SimplePOJO simplePOJO) {
// TransactionSynchronizationManager.isActualTransactionActive() -> true
MyDelegate myDelegate = applicationContext.getBean(MyDelegate.class);
myDelegate.setSimplePOJO(simplePOJO);
taskExecutor.execute(myDelegate);
}
}
以这种方式配置ThreadPoolTaskExecutor:
<bean id="taskExecutor"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="1" />
<property name="maxPoolSize" value="5" />
<property name="queueCapacity" value="25" />
</bean>
最终应该在每个任务的新事务中启动异步工作:
@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class MyDelegate implements Runnable {
private SimplePOJO simplePOJO;
@Override
public void run() {
// TransactionSynchronizationManager.isActualTransactionActive()); -> False!
if (this.simplePOJO != null) {
this.doStuff(angebotAnfrageContainer);
}
}
public void setSimplePOJO(SimplePOJO simplePOJO) {
this.simplePOJO = simplePOJO;
}
@Async
@Transactional(propagation = Propagation.REQUIRES_NEW)
private void doStuff() {
// TransactionSynchronizationManager.isActualTransactionActive()); -> False!
// do stuff with the pojos data in the transaction (persist on DB)
}
}
你对我在这里缺少什么有什么建议吗?
非常感谢提前!
我尝试了什么 写上面的代码&amp;在网上搜了几个小时,这就是我发现的:
我不得不承认我对Spring很新,并且还没有很好地理解框架。在尝试和搜索网络的最后几个小时内,我认为它与从春天创建的Proxys beeing有关,当我调用execute() - Method或当TaskRunner调用run()时链断裂 - 相反的方法调用代理直接调用实现(MyDelegate)...但我绝对没有想法如何验证或更改它。
非常感谢提前
答案 0 :(得分:3)
使用AOP应用交易。默认情况下,Spring使用proxies来应用AOP。代理的使用导致只有调用(外部方法调用)对象被拦截。在你的情况下,你正在从对象内部进行一个方法调用,它不会通过代理并且不会被拦截,基本上会使你的@Transactional
无用。
只需将@Transactional
移动到run
方法即可解决您的问题,因为run
方法现在将在事务中运行。
@Transactional
public void run() {...}
你也可以删除@Async
,因为这里没有做任何事情,你正在执行任务TaskExecutor
已经使它们异步(取决于你使用的TaskExecutor
)。
链接: