Spring Boot延遲執(zhí)行實(shí)現(xiàn)方法
說明:本文介紹如何在Spring Boot項(xiàng)目中,延遲執(zhí)行某方法,及討論延遲執(zhí)行方法的事務(wù)問題。
搭建Demo
首先,創(chuàng)建一個(gè)Spring Boot項(xiàng)目,pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.12</version>
<relativePath/>
</parent>
<groupId>com.hezy</groupId>
<artifactId>delay_thread_demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.8</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
</dependencies>
</project>寫個(gè)接口,打印進(jìn)入方法時(shí)的時(shí)間
import com.hezy.service.DelayService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.text.SimpleDateFormat;
import java.util.Date;
@RestController
@RequestMapping("/demo")
@Log4j2
public class DemoController {
@Autowired
private DelayService delayService;
@GetMapping
public String demo() {
return "Hello World!";
}
@GetMapping("/delay1/{time}")
public String delay1(@PathVariable Integer time) {
log.info("enter delay1...date={} time={}",
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), time);
delayService.delay1(time);
return "success";
}
}延遲執(zhí)行實(shí)現(xiàn)
delayService,delay1()實(shí)現(xiàn),如下:
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
/**
* 延遲執(zhí)行
* @param time
*/
public void delay1(Integer time) {
scheduler.schedule(() -> {
log.info("run delay1...date={} time={}",
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), time);
}, time, TimeUnit.SECONDS);
}就是開了一個(gè)線程來執(zhí)行,可設(shè)置延遲時(shí)間。啟動(dòng)項(xiàng)目,測試,如下:
(發(fā)送請求,響應(yīng)結(jié)果即刻返回)

(控制臺(tái)可見任務(wù)延遲5秒執(zhí)行)

事務(wù)問題
寫個(gè)實(shí)體類
import lombok.Data;
@Data
public class User {
private Integer id;
private String username;
private String password;
}再寫個(gè)Mapper,里面寫個(gè)insert()方法
import com.hezy.pojo.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper {
@Insert("insert into user (id, username, password) values (#{id}, #{username}, #{password})")
void insert(User user);
}新建個(gè)延遲方法,delay2(),方法生加聲明式注解,方法內(nèi)手動(dòng)制造一個(gè)異常
(controller)
@PostMapping("/delay2/{time}")
public String delay2(@RequestBody User user, @PathVariable Integer time) {
log.info("enter delay2...date={} time={}",
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), time);
delayService.delay2(user, time);
return "success";
}(service)
/**
* 聲明式事務(wù)
*/
@Transactional(rollbackFor = Exception.class)
public void delay2(User user, Integer time) {
scheduler.schedule(() -> {
log.info("run delay2...date={} time={}",
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), time);
userMapper.insert(user);
int i = 1 / 0;
user.setId(3);
userMapper.insert(user);
}, time, TimeUnit.SECONDS);
}啟動(dòng)項(xiàng)目,調(diào)用方法

控制臺(tái)沒有報(bào)錯(cuò)

數(shù)據(jù)庫,插入了一條數(shù)據(jù),事務(wù)沒有控制住

以上說明,聲明式事務(wù)無法控制延遲執(zhí)行的方法,并且異常也被線程內(nèi)捕獲了,沒有拋出來。
編程式事務(wù)
試下編程式事務(wù),手動(dòng)實(shí)現(xiàn)事務(wù),如下:
(controller)
@PostMapping("/delay3/{time}")
public String delay3(@RequestBody User user, @PathVariable Integer time) {
log.info("enter delay3...date={} time={}",
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), time);
delayService.delay3(user, time);
return "success";
}(service)
@Autowired
private PlatformTransactionManager transactionManager;
/**
* 編程式事務(wù)
*/
public void delay3(User user, Integer time) {
scheduler.schedule(() -> {
TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
try {
log.info("run delay3...date={} time={}",
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), time);
userMapper.insert(user);
// 故意產(chǎn)生異常
int i = 1 / 0;
user.setId(3);
userMapper.insert(user);
// 提交事務(wù)
transactionManager.commit(status);
} catch (Exception e) {
transactionManager.rollback(status);
e.printStackTrace();
}
}, time, TimeUnit.SECONDS);
}把數(shù)據(jù)庫記錄刪掉,啟動(dòng)項(xiàng)目,測試

控制臺(tái)報(bào)錯(cuò)

數(shù)據(jù)庫沒有插入記錄,編程式事務(wù)控制住了

總結(jié)
本文介紹了在Spring Boot項(xiàng)目中延遲執(zhí)行方法的實(shí)現(xiàn),以及延遲執(zhí)行下聲明式事務(wù)和編程式事務(wù)的使用情況。
完整源碼:https://github.com/HeZhongYing/delay_thread_demo
到此這篇關(guān)于Spring Boot延遲執(zhí)行實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Spring Boot延遲執(zhí)行內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用java + selenium + OpenCV破解網(wǎng)易易盾滑動(dòng)驗(yàn)證碼的示例
這篇文章主要介紹了使用java + selenium + OpenCV破解網(wǎng)易易盾滑動(dòng)驗(yàn)證碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02
Springboot如何配置yml文件與映射到j(luò)ava類
這篇文章主要介紹了Springboot如何配置yml文件與映射到j(luò)ava類問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09
SpringCloud Gateway網(wǎng)關(guān)功能介紹與使用
SpringCloud Gateway 是 Spring Cloud 的一個(gè)全新項(xiàng)目,它旨在為微服務(wù)架構(gòu)提供一種簡單有效的統(tǒng)一的 API 路由管理方式。這篇文章主要介紹了SpringCloud Gateway網(wǎng)關(guān)作用,需要的朋友可以參考下2022-12-12
Spring框架學(xué)習(xí)之Spring?@Autowired實(shí)現(xiàn)自動(dòng)裝配的代碼
自動(dòng)裝配就是說,你不用手動(dòng)實(shí)現(xiàn)bean之間的組合關(guān)系,只要使用了@Autowired注解,程序就會(huì)自動(dòng)的注入這個(gè)需要的bean,前提是你的Spring容器有這個(gè)bean,這篇文章主要介紹了Spring?@Autowired實(shí)現(xiàn)自動(dòng)裝配,需要的朋友可以參考下2021-12-12

