不学编程都能看懂的@Transactional()事务
后端三郎:一名99年的寶藏開發男孩兒
看咱關系:文章對你有用的話,點贊打卡
目錄
背景原因
框架版本
代碼示例
表結構和數據
MjjFoodModel實體類
Controller方法
FoodService 接口
FoodServiceImpl 實現類
MjjFoodModelMapper接口
不加事務結果
使用事務結果
屬性用法
背景原因
? ? ? ? 假設我們接口修改數據,接口處理了一半,數據已經入庫了,處理另一半的時候報錯了,此時我們要保證已經處理完的數據回滾到未處理之前,保證數據的原子性。
? ? ? ? Spring的@Transactional注解可以很方便的開啟事務,但是默認只在遇到運行時異常和Error時才會回滾,非運行時異常不回滾,即Exception的子類中,除了RuntimeException及其子類,其他的類默認不回滾。
框架版本
SpringBoot——2.4.1
Lombok——1.18.16
Mybatis-Plus——3.4.2
MySql——8.0.22
代碼示例
表結構和數據
SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0;-- ---------------------------- -- Table structure for mjj_food_model -- ---------------------------- DROP TABLE IF EXISTS `mjj_food_model`; CREATE TABLE `mjj_food_model` (`id` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '主鍵ID(uuid)',`food_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '美食名稱',`food_brief` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '美食簡介',`food_picture` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '美食圖片',`city_id` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '城市ID',`city_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '城市名稱',`create_id` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '創建人ID',`create_time` datetime(0) NULL DEFAULT NULL COMMENT '創建時間',`update_id` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '修改人ID',`update_time` datetime(0) NULL DEFAULT NULL COMMENT '修改時間',`is_delete` tinyint(1) NULL DEFAULT NULL COMMENT '是否刪除',PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '美食特產表' ROW_FORMAT = Dynamic;-- ---------------------------- -- Records of mjj_food_model -- ---------------------------- INSERT INTO `mjj_food_model` VALUES ('c525acf0-7763-11ec-996d-00163e0c3e0d', '牛肉丸子面', '臨汾以牛肉丸子面最為有名,屬于清真美食,牛肉丸子湯遍布臨汾,一碗端上來,厚厚的紅油看著就很有食欲,湯底是用牛骨高湯熬制,有嚼勁的丸子和勁道的面相互搭配,再加上青菜點綴,吃起來香、辣、麻,一碗下肚,很是過癮。', '牛肉面圖片', '167fa911-776e-11ec-996d-00163e0c3e0d', '臨汾', '1', '2022-01-18 15:16:58', '1', '2022-01-18 15:17:05', 1);SET FOREIGN_KEY_CHECKS = 1;MjjFoodModel實體類
package com.example.demo.entity.food;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;import java.time.LocalDateTime;@AllArgsConstructor//有參構造方法 @NoArgsConstructor//無參構造方法 @Data public class MjjFoodModel {/***美食特產主鍵ID*/private String id;/***美食名稱*/private String foodName;/***美食簡介*/private String foodBrief;/***美食圖片*/private String foodPicture;/***城市ID*/private String cityId;/***城市名稱*/private String cityName;/***創建人ID*/private String createId;/***創建時間*/private LocalDateTime createTime;/***修改人ID*/private String updateId;/***修改時間*/private LocalDateTime updateTime;/***是否刪除 true(1)未刪除 false(0)刪除*/private Boolean isDelete;}Controller方法
@RestController @RequestMapping(value = "/food") //swagger注解,不用可以刪除 @Api(value = "后端三郎and前端小馬",tags = "李淳罡VS曹長卿————美食模塊") public class FoodController {@Resourceprivate FoodService foodService;@GetMapping(value = "/save")//swagger注解,不用可以刪除@ApiOperation(value = "美食特產編輯",httpMethod = "GET",notes = "美食特產編輯")public void save(){foodService.save();} }FoodService 接口
void save();FoodServiceImpl 實現類
@Resourceprivate MjjFoodModelMapper mjjFoodModelMapper;@Overridepublic void save() {//創建實體類MjjFoodModel mjjFoodModel = new MjjFoodModel();//復制主鍵ID為UUIDmjjFoodModel.setId(UUID.randomUUID().toString());//美食名稱mjjFoodModel.setFoodName("美食名稱");//新增mjjFoodModelMapper.insert(mjjFoodModel);//寫個BUG,使程序出現錯誤int a = 4/0;}MjjFoodModelMapper接口
@Mapper public interface MjjFoodModelMapper extends BaseMapper<MjjFoodModel> {}不加事務結果
????????啟動項目,訪問localhost:8081/food/save測試(端口號自己配置的)
? ? ? ? ? ? ?注:500的錯誤是我們故意寫錯的,為了看數據是否會回滾
? ? ? ? ?接口運行一半報錯,此時我們查看數據發現數據卻添加進去了,此時會對我們的數據造成臟數據,因為報錯了你再次請求的時候就會有多條數據。不符合我們的業務邏輯。
使用事務結果
? ? ? ? 在FoodServiceImpl 實現類的save方法上邊加上@Transactional注解,再次測試
@Override@Transactionalpublic void save() {//創建實體類MjjFoodModel mjjFoodModel = new MjjFoodModel();//復制主鍵ID為UUIDmjjFoodModel.setId(UUID.randomUUID().toString());//美食名稱mjjFoodModel.setFoodName("美食名稱");//新增mjjFoodModelMapper.insert(mjjFoodModel);//寫個BUG,使程序出現錯誤int a = 4/0;}? ? ? ? ?啟動項目,訪問localhost:8081/food/save測試,接口依然報錯,但是我們的數據沒有添加進去,遇到異常數據進行了回滾。數據還是保持原樣。
屬性用法
readOnly:讀寫或只讀事務,true代表只讀,false代表讀寫,默認讀寫false,例如@Transactional(readOnly = true)。
rollbackFor:解決了只有運行時異常和Error才回滾的問題,用于指定回滾的異常類型。例如@Transactional(rollbackFor = Exception.class),用的Exception頂級異常,包含了所有的子類,所有的異常都可以回滾。
noRollbackFor:意思是遇到異常不進行回滾,例如@Transactional(rollbackFor = Exception.class),用的Exception頂級異常,包含了所有的子類,所有的異常都不回滾。和上一個正好相反。
propagation:事務的傳播行為,默認的是REQUIRED
- REQUIRED 支持當前已經存在的事務,如果還沒有事務,就創建一個新事務。
- MANDATORY 支持當前已經存在的事務,如果還沒有事務,就拋出一個異常。
- NESTED 在當前事務中創建一個嵌套事務,如果還沒有事務,那么就簡單地創建一個新事務。
- REQUIRES_NEW 掛起當前事務,創建一個新事務,如果還沒有事務,就簡單地創建一個新事務。
- NEVER 強制要求不在事務中運行,如果當前存在一個事務,則拋出異常。
- NOT_SUPPORTED 強制不在事務中運行,如果當前存在一個事務,則掛起該事務。
- SUPPORTS 支持當前事務,如果沒有事務那么就不在事務中運行。
timeout:事務的超時設置,如果超過該時間限制但事務還沒有完成,則自動回滾事務。默認沒有時間限制。
isolation:事務的隔離級別,使用默認的即可
總結
以上是生活随笔為你收集整理的不学编程都能看懂的@Transactional()事务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Debian 安装 git
- 下一篇: 婚宴座位图html5,大型婚宴 婚礼座位