我正在尝试在服务层代码中进行异步方法调用。一些伪代码如下:
public void createXXX ()
{
dao.saveOrUpdate(entity); // save an entity
...................
...................
callAServiceXXX ()
}
...........
...........
public void callAServiceXXX()
{
SomeEntity entity = dao.getEntity(); // entity NOT NULL
this.threadPoolTaskExecutor.execute(new Runnable() {
public void run() {
try {
callAMethodXXX()
}catch()
{}
}
public void callAMethodXXX()
{
SomeEntity entity = dao.getEntity(); // entity always NULL
}
我的spring配置文件为包含上述逻辑的服务层bean定义了以下内容:
<property name="transactionAttributes">
<props>
<prop key="callAServiceXXX">PROPAGATION_REQUIRED</prop>
<prop key="callAMethodXXX">PROPAGATION_MANDATORY</prop>
</props>
</property>
如上所述,当我试图获取我在方法createXXX()中保存的实体对象时,当从callAMethodXXX()方法执行dao调用时,它总是为NULL。
我不确定这种行为的原因。在spring配置文件中尝试了一些其他事务属性但没有取得任何成功。
我试图让这项工作的解决方法是:
1)创建一个帮助器类。在此服务层类中注入它。
2)将方法callAMethodXXX()转移到此助手类。
3)定义<prop key="callAMethodXXX">PROPAGATION_REQUIRES_NEW</prop>
因为我想确保callAMethodXXX()应该在新的事务中执行。
但是,我不想使用额外的帮助程序类,并且希望确保逻辑在单个服务层类中正常工作。
上述任何输入都会有所帮助。
问候,
答案 0 :(得分:0)
您的Runnable线程不知道事务管理。 也许您可以尝试向托管bean添加对自身的引用,并为方法callAMethod添加TRANSACTION_REQUIRES_NEW:
@Component
public class MyService {
@Autowired
public MyService myService;
public void callAServiceXXX() {
SomeEntity entity = dao.getEntity();
this.threadPoolTaskExecutor.execute(new Runnable() {
public void run() {
try {
myService.callAMethodXXX();
}catch(Exception e){
}
}
});
}
}
<property name="transactionAttributes">
<props>
<prop key="callAServiceXXX">PROPAGATION_REQUIRED</prop>
<prop key="callAMethodXXX">PROPAGATION_REQUIRES_NEW</prop>
</props>
</property>
免责声明:您可能仍然遇到这种方法的问题,因为您正在调用异步方法,并且您不能100%确定单独事务中的saveOrUpdate方法是否已完成。