场景描述:项目中有一个数据拷贝的功能,项目接口响应时间是2分钟,当数据量比较大的时候,该功能接口响应时间会超过2分钟,前端就会报服务未响应的错,其实是后端还在处理数据。
解决方案:原接口实现方式,改为多线程,只有一个子线程和一个主线程。所有的数据处理全部放入子线程中,当前端请求的时候,主线程中开启子线程去执行数据处理等业务,然后直接返回一个标志,表示接口能正常访问。在子线程中,处理数据拷贝要做的事情,引用rabbitMQ,在拷贝数据的同时,发送拷贝进度消息给前端。原拷贝接口要返回的数据也通过消息返回前端。这里采用消息机制,而不用前端轮询访问接口,节省资源。消息使用direct发布模式(1对1),(消息机制相关文章)子线程创建是在原结构中,添加了实现runnable接口的内部类,然后主线程调用子线程。子线程中事务的处理,采用手动事务,事务注解在子线程中有问题。
手动事务写法:
@Autowired
private DataSourceTransactionManager transactionManager;
//1.获取事务定义
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
//2.设置事务隔离级别,开启新事务
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
//3.获得事务状态
TransactionStatus status = transactionManager.getTransaction(def);
// 事务回滚
transactionManager.rollback(status);
// 事务提交
transactionManager.commit(status);
相关代码片段