Spring RestService异步日志记录功能

时间:2018-09-29 21:29:55

标签: spring asynchronous callable

我在春季写的休息服务运行得很好。

现在,我需要添加执行一些数据库事务,然后再将响应返回给用户。

此数据库事务独立于检索到的响应。

例如,

@PostMapping("login")
    public TransactionResponse loginAuthentication(@Valid @RequestBody LoginRequestBody loginRequest) {
        TransactionResponse transactionResponse = new TransactionResponse();
        try {
            transactionResponse = loginService.validateUser(loginRequest);

            //independent transaction needs to be executed in a separate thread
            loginSerice.addLoginLog(transactionResponse);

            //return below response without waiting to compelete above log transaction
            return transactionResponse; 
        }
        catch (Exception e) {
            return CommonUtils.setErrorResponse(transactionResponse, e);
        }

    }

我在spring mvc link中阅读了异步控制器。虽然控制器  在单独的线程中执行各自的功能,但是我不想等待数据库事务完成。 从服务层获得响应后,应立即将其转发给用户。

任何建议!

春季版本为4.3

1 个答案:

答案 0 :(得分:0)

我发布了此答案,以帮助具有相同需求(在单独的线程中执行void函数)的其他开发人员。

由于我没有多线程/异步环境的经验,所以我想通过使用Spring异步方法来简化它。

因此,首先,我创建了线程池

@Configuration
@EnableAsync
public class ThreadConfig {

    @Bean
    public TaskExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(4);
        executor.setMaxPoolSize(4);
        executor.setThreadNamePrefix("WEBAPP");
        executor.initialize();

        return executor;
    }
}

然后,我创建了一个服务,该服务将在单独的线程中执行我的代码。

@Async
@Service
@Transactional
public class LoggingService {

    public void logintransaction() throws Exception{ 
        System.out.println("start login loggin");

        Thread.sleep(5000);

        System.out.println("exit");
    }

}

最后,我在控制器上调用了上述服务。如我所见,首先打印了Total Time Taken,然后打印了“开始登录登录”。这意味着我的新方法在新线程中执行。

@Autowired
    private LoggingService loggingService;


    @PostMapping("login")
    public TransactionResponse loginAuthentication(@Valid @RequestBody LoginRequestBody loginRequest) {
        long startTime = System.currentTimeMillis();
        TransactionResponse transactionResponse = new TransactionResponse();
        try {
            transactionResponse = loginService.validateUser(loginRequest);

            //independent transaction needs to be executed in a separate thread
            //loginSerice.addLoginLog(transactionResponse);
            loggingService.logintransaction();

            //return below response without waiting to compelete above log transaction

            System.err.println("Total Time Taken=>"+(System.currentTimeMillis() - startTime));
            return transactionResponse; 
        }
        catch (Exception e) {
            return CommonUtils.setErrorResponse(transactionResponse, e);
        }

    }

谢谢