Spring Boot延遲執(zhí)行實現(xiàn)方法
說明:本文介紹如何在Spring Boot項目中,延遲執(zhí)行某方法,及討論延遲執(zhí)行方法的事務問題。
搭建Demo
首先,創(chuàng)建一個Spring Boot項目,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>
寫個接口,打印進入方法時的時間
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í)行實現(xiàn)
delayService,delay1()實現(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); }
就是開了一個線程來執(zhí)行,可設置延遲時間。啟動項目,測試,如下:
(發(fā)送請求,響應結(jié)果即刻返回)
(控制臺可見任務延遲5秒執(zhí)行)
事務問題
寫個實體類
import lombok.Data; @Data public class User { private Integer id; private String username; private String password; }
再寫個Mapper,里面寫個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); }
新建個延遲方法,delay2(),方法生加聲明式注解
,方法內(nèi)手動制造一個異常
(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)
/** * 聲明式事務 */ @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); }
啟動項目,調(diào)用方法
控制臺沒有報錯
數(shù)據(jù)庫,插入了一條數(shù)據(jù),事務沒有控制住
以上說明,聲明式事務無法控制延遲執(zhí)行的方法,并且異常也被線程內(nèi)捕獲了,沒有拋出來。
編程式事務
試下編程式事務,手動實現(xiàn)事務,如下:
(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; /** * 編程式事務 */ 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); // 提交事務 transactionManager.commit(status); } catch (Exception e) { transactionManager.rollback(status); e.printStackTrace(); } }, time, TimeUnit.SECONDS); }
把數(shù)據(jù)庫記錄刪掉,啟動項目,測試
控制臺報錯
數(shù)據(jù)庫沒有插入記錄,編程式事務控制住了
總結(jié)
本文介紹了在Spring Boot項目中延遲執(zhí)行方法的實現(xiàn),以及延遲執(zhí)行下聲明式事務和編程式事務的使用情況。
完整源碼:https://github.com/HeZhongYing/delay_thread_demo
到此這篇關(guān)于Spring Boot延遲執(zhí)行實現(xiàn)的文章就介紹到這了,更多相關(guān)Spring Boot延遲執(zhí)行內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
slf4j?jcl?jul?log4j1?log4j2?logback各組件系統(tǒng)日志切換
這篇文章主要介紹了slf4j、jcl、jul、log4j1、log4j2、logback的大總結(jié),各個組件的jar包以及目前系統(tǒng)日志需要切換實現(xiàn)方式的方法,有需要的朋友可以借鑒參考下2022-03-03關(guān)于MVC的dao層、service層和controller層詳解
這篇文章主要介紹了關(guān)于MVC的dao層、service層和controller層詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02Spring AOP定義AfterReturning增加實例分析
這篇文章主要介紹了Spring AOP定義AfterReturning增加,結(jié)合實例形式分析了Spring面相切面AOP定義AfterReturning增加相關(guān)操作技巧與使用注意事項,需要的朋友可以參考下2020-01-01使用Mybatis時SqlSessionFactory對象總是報空指針
本文主要介紹了使用Mybatis時SqlSessionFactory對象總是報空指針,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-09-09FilenameUtils.getName?函數(shù)源碼分析
這篇文章主要為大家介紹了FilenameUtils.getName?函數(shù)源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-09-09SpringBoot靜態(tài)資源映射規(guī)則淺析
這篇文章主要介紹了SpringBoot靜態(tài)資源映射規(guī)則,今天在玩SpringBoot的demo的時候,放了張圖片在resources目錄下,啟動區(qū)訪問的時候,突然好奇是識別哪些文件夾來展示靜態(tài)資源的, 為什么有時候放的文件夾不能顯示,有的卻可以2023-02-02基于Java語言在窗體上實現(xiàn)飛機大戰(zhàn)小游戲的完整步驟
這篇文章主要給大家介紹了基于Java語言在窗體上實現(xiàn)飛機大戰(zhàn)小游戲的完整步驟,文中通過圖文以及實例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2022-02-02