Spring Restservice Асинхронное ведение журнала функциональности - PullRequest
0 голосов
/ 30 сентября 2018

Весной я написал службы отдыха, которые работают отлично.

Теперь мне нужно добавить несколько транзакций в БД, прежде чем возвращать ответ пользователю.

Эта транзакция БД не зависит от полученного ответа.

Например,

@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);
        }

    }

Я читаю на асинхронном контроллере весной mvc link .Хотя контроллер выполняет соответствующие функции в отдельном потоке, но я не хочу ждать завершения транзакции в БД. После получения ответа от сервисного уровня он должен быть перенаправлен пользователю без каких-либо задержек.

Любые предложения !!

Версия Spring - 4.3

1 Ответ

0 голосов
/ 01 октября 2018

Я опубликовал этот ответ, чтобы помочь коллегам-разработчикам с такими же требованиями (выполнить функцию void в отдельном потоке).

Поскольку у меня нет опыта работы в многопоточной / асинхронной среде, я хочу упростить его, используя пружинные асинхронные методы.

Итак, сначала я создал пул потоков

@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, затем печатается "start login loggin".Это означает, что мой новый метод выполняется в новом потоке.

@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);
        }

    }

Спасибо

...