有时候,在代码中,有些对象是没有注入到spring容器中的,比如实现runnable接口的多线程task,他里边的方法调用,就不会支持事物,因为没有注入spring,spring不会进行管理,就不支持事物,因此打了@transaction注解也没有用。
这种情况下就需要手动添加事物,或者单独写接口,让他支持事物,最终目的,是让这个方法支持事物,最近想了写了一个公用的方法,让他支持事物,其实就是给不支持事物的方法,外边包了一层支持事物的外衣。
1.建立接口:
public interface TransactionalSupportService {
/**
* 声明新的事务,然后执行业务代码
* @param consumer
*/
void newHxTransactional(Consumer consumer);
}
public interface Consumer {
//对具体业务代码的传递
void accept(T t);
}
2.实现事物接口TransactionalSupportService
@Service
public class TransactionalSupportServiceImplimplements TransactionalSupportService {
//这个接口交给了spring管理,并且支持事物
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void newHxTransactional(Consumer consumer) {
consumer.accept(null);
}
}
3.使用:
@Slf4j
public class CxjmyltsrqrdUpdateCbxzAndSaveRdmxTaskimplements Runnable {
private TransactionalSupportServicetransactionalSupportService;
@Override
public void run() {
for (final CxjmyltsrqrdDrmxDTO mxDTO : mxDtos) {
//使用匿名内部类,执行具体的业务方法
transactionalSupportService.newHxTransactional(new Consumer(){
@Override
public void accept(Object dto) {
this.automaticChangeCbxz(mxDTO); //私有方法不支持事物
}
});
}
}
4.总结:从代码可以清晰的看出,就是给不支持事物的方法外边包裹了一层支持事物的外衣,其实这就是代理模式的思想,在某个方法执行的时候,代理类对目标对象进行一些别的处理,进行增强,这里的匿名内部类Consumer相当于代理类,newHxTransactional事物方法对目标进行增强。
顺便说一句,所谓设计模式,它不是一种标准的代码模版,它是一种思想。
网友评论