最近涉及到了一些spring的异步任务的了解,虽然我没去写相关的代码,不过还是去了解了很多,此处做一些记录。
spring异步任务配置
在spring的配置文件之中,增加task的配置,包含相关的约束的引用和相关的设置。
具体如下:在xmlns中添加task,在xsi中加入具体的约束地址。增加
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation=http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd
增加task的配置,这里可能有小伙伴配置过spring定时就会发现,配置是一个,其也确实是一个,看了下约束,里面说的很清楚,是给定时的注释和异步任务的注释使用的。
Enables the detection of @Async and @Scheduled annotations on any Spring-managed
object.
这里说明下,连接池是自己配置的,因为有别的需求,官方的说明如下:
Specifies the java.util.Executor instance to use when invoking asynchronous methods.
If not provided, an instance of org.springframework.core.task.SimpleAsyncTaskExecutor
will be used by default.
然后具体的连接池配置如下:
到这里,配置方面已经说清楚了,下面说下使用吧。
spring异步任务执行
使用很简单 ,在service里面,需要异步执行的方法,添加@Async这个注释即可,,这个任务就会异步执行。
代码如下:
@Service
public class TestServiceImpl implements TestService {
@Async
@Override
public void runTheTest(){
System.out.println("执行11111");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("执行22222");
}
}
spring异步任务的事务
说到事务就毕竟麻烦,之前网上查了一下,说不能直接在这个异步任务里面直接加事务,需要引用其他service里面的加事务。项目本身是aop来进行事务的管理,然后再service里面引入了两个其他的service。
代码入下:
@Service
public class TestServiceImpl implements TestService {
@Autowired
private BigDataMessageService bigDataMessageService;
private SqCoursewareService sqCoursewareService;
@Async
@Override
public void runTheTest(){
System.out.println("执行11111");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
List messageList = new ArrayList();
WarningMessage a = new WarningMessage();
a.setUnitId("999");
a.setUserId("000");
a.setCreationTime(new Date());
a.setMessage("999000");
a.setType(1);
a.setResult("000999");
messageList.add(a);
bigDataMessageService.insertWarningMessage(messageList);
sqCoursewareService.selectByPrimaryKey(1);
}
}
这里第二个service实际没有注入,所以运行实际这个方法会报空指针异常。首先屏蔽掉 sqCoursewareService.selectByPrimaryKey(1);
这个方法,结果正常插入。
之后解除屏蔽,抛出了空指针异常,同时插入的数据被回滚。
本身单个没有引用有事务的service,测试结果实际也是被回滚了。
代码如下:
@Service
public class TestServiceImpl implements TestService {
@Autowired
private BigDataMessageMapper bigDataMessageMapper;
@Async
@Override
public void runTheTest(){
System.out.println("执行11111");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
List messageList = new ArrayList();
WarningMessage a = new WarningMessage();
a.setUnitId("991");
a.setUserId("001");
a.setCreationTime(new Date());
a.setMessage("991001");
a.setType(1);
a.setResult("001991");
messageList.add(a);
bigDataMessageMapper.insertWarningMessage(messageList);
Integer.valueOf(testFunction());
System.out.println("执行222222");
}
private String testFunction(){
return null;
}
}
这里直接引入Mapper,Mapper实际是没有事务的,然后
Integer.valueOf(testFunction());
这里会抛异常,结果是插入同样被回滚了。
也许网上说的情况和我测试的不一致,也许是spring版本的原因,这里时间有限没有进一步的测试了。小伙伴如果知道是哪里有问题可以告诉我下,然后写的话,尽量本身不要涉及事务,然后引用的service里面加上事务吧。