SpringBoot使用@Async实现异步调用

SpringBoot使用@Async实现异步调用

Posted by John Doe on 2020-08-08
Words 368 and Reading Time 1 Minutes
Viewed Times

背景

在写项目时,有个需求为前端使用用户下载数据库备份压缩文件,其中涉及多表多条件dump备份

部分代码

类似方法有4个,未异步调用耗时较长影响用户体验。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public void entIdSqlDumpOne(String path, String dateString, String ent_id,String entTableName,String user, String password, String hostIP, String exportDatabaseName){
String folderName_1 = "ZYK_" + ent_id + "_BackupENT_" + dateString + ".sql";
PrintWriter printWriter = null;
BufferedReader bufferedReader = null;
//Lock lock = new ReentrantLock();
try {
//lock.lock();
printWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(path + folderName_1), "utf8"));
Process process = Runtime.getRuntime().exec(" mysqldump -h" + hostIP + " -u" + user + " -p" + password + " --set-charset=UTF8 " + exportDatabaseName +" --tables "+entTableName+" "+"--where=\"ent_id='"+ ent_id + "'\"");
InputStreamReader inputStreamReader = new InputStreamReader(process.getInputStream(), "utf8");
bufferedReader = new BufferedReader(inputStreamReader);
String line;
while ((line = bufferedReader.readLine()) != null) {
printWriter.println(line);
}
printWriter.flush();
if (process.waitFor() != 0) {
throw new CustomException("线程未正常中止");
}
} catch (Exception e) {
e.printStackTrace();
throw new CustomException("备份sql操作失败");
} finally {
try {
if (bufferedReader != null) {
bufferedReader.close();
}
if (printWriter != null) {
printWriter.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

设置异步调用

步骤

  1. springboot application类中配置@EnableAsync

    1
    2
    3
    4
    5
    6
    7
    @SpringBootApplication 
    @EnableAsync
    public class SpringbootAsyncApplication {
       public static void main(String[] args) {        
    SpringApplication.run(SpringbootAsyncApplication.class, args);  
    }
    }
  2. 在需要异步调用的方法头加@Async注解

  3. 异步调用备份方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
   public void testTask() throws Exception{
long start = System.currentTimeMillis();
       Future<String> task1 = myTask.entIdSqlDumpOne();
       Future<String> task2 = myTask.entIdSqlDumpTwo();
       Future<String> task3 = myTask.entIdSqlDumpThree();
       while(true) {
           if(task1.isDone() && task2.isDone() && task3.isDone()) {
               // 三个任务都调用完成,退出循环等待,无法调度完成抛出异常
               break;
          }
           Thread.sleep(1000);
      }
long end = System.currentTimeMillis();
}

This is copyright.

...

...

00:00
00:00