面試突擊87:說一下 Spring 事務傳播機制?( 二 )


不支持當前事務的“女生”也分為 3 種(強勢型或者叫事業型):

  • Propagation.REQUIRES_NEW:不要你的房子,必須一起賺錢買房子 。
  • Propagation.NOT_SUPPORTED:不要你的房子,必須一起租房子 。
  • Propagation.NEVER:必須一起租房子 , 你有房子就分手 。
最后一種是嵌套性事務 Propagation.NESTED , 它屬于懂事型女友,如果有房子了就以房子為基礎做點小生意,賣個花生、水果啥的,如果買賣成了,那就繼續發展;如果失敗了,至少還有房子;如果沒房子也沒關系,一起賺錢買房子 。
事務傳播機制使用與演示接下來我們演示一下事務傳播機制的使用,以下面 3 個最典型的事務傳播級別為例:
  • 支持當前事務的 REQUIRED;
  • 不支持當前事務的 REQUIRES_NEW;
  • 嵌套事務 NESTED 。
下來我們分別來看 。
事務傳播機制的示例,需要用到以下兩張表:
-- 用戶表CREATE TABLE `user` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `name` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,  `password` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,  `createtime` datetime DEFAULT CURRENT_TIMESTAMP,  PRIMARY KEY (`id`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin ROW_FORMAT=DYNAMIC;-- 日志表CREATE TABLE `log` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `content` text NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;創建一個 Spring Boot 項目,核心業務代碼有 3 個:UserController、UserServcie 以及 LogService 。在 UserController 里面調用 UserService 添加用戶,并調用 LogService 添加日志 。
REQUIRED 使用演示REQUIRED 支持當前事務 。UserController 實現代碼如下,其中 save 方法開啟了事務:
@RestControllerpublic class UserController {    @Resource    private UserService userService;    @Resource    private LogService logService;    @RequestMapping("/save")    @Transactional    public Object save(User user) {        // 插入用戶操作        userService.save(user);        // 插入日志        logService.saveLog("用戶插入:" + user.getName());        return true;    }}UserService 實現代碼如下:
@Servicepublic class UserService {    @Resource    private UserMapper userMapper;    @Transactional(propagation = Propagation.REQUIRED)    public int save(User user) {        return userMapper.save(user);    }}LogService 實現代碼如下:
@Servicepublic class LogService {    @Resource    private LogMapper logMapper;    @Transactional(propagation = Propagation.REQUIRED)    public int saveLog(String content) {        // 出現異常        int i = 10 / 0;        return logMapper.saveLog(content);    }}執行結果:程序報錯,兩張表中都沒有插入任何數據 。
執行流程描述:
  1. 首先 UserService 中的添加用戶方法正常執行完成 。
  2. LogService 保存日志程序報錯,因為使用的是 UserController 中的全局事務,所以整個事務回滾,步驟 1 中的操作也跟著回滾 。
  3. 所以數據庫中沒有添加任何數據 。
REQUIRED_NEW 使用演示REQUIRED_NEW 不支持當前事務 。UserController 實現代碼:
@RequestMapping("/save")@Transactionalpublic Object save(User user) {    // 插入用戶操作    userService.save(user);    // 插入日志    logService.saveLog("用戶插入:" + user.getName());    return true;}

推薦閱讀