前言
- 數(shù)據(jù)庫(kù)事務(wù)(簡(jiǎn)稱:事務(wù))是數(shù)據(jù)庫(kù)管理系統(tǒng)執(zhí)行過(guò)程中的一個(gè)邏輯單位,由一個(gè)有限的數(shù)據(jù)庫(kù)操作序列構(gòu)成炊昆。
- 事務(wù)的作用就是為了保證用戶的每一個(gè)操作都是可靠的缝其,事務(wù)中的每一步操作都必須成功執(zhí)行盗胀,只要有發(fā)生異常就回退到事務(wù)開(kāi)始未進(jìn)行操作的狀態(tài)官边。
- springboot開(kāi)啟事務(wù)很簡(jiǎn)單沸手,只需要一個(gè)注解@Transactional 就可以了。因?yàn)樵趕pringboot中已經(jīng)默認(rèn)對(duì)jpa拒逮、jdbc罐氨、mybatis開(kāi)啟了事事務(wù)臀规,引入它們依賴的時(shí)候滩援,事物就默認(rèn)開(kāi)啟。當(dāng)然塔嬉,如果你需要用其他的orm玩徊,比如beatlsql,就需要自己配置相關(guān)的事物管理器谨究。
1恩袱、配置文件application.yml
本文使用的是之前整合JPA的文章,具體可以參考 SpringBoot 整合JPA胶哲。這里的jpa配置略微不同畔塔,原因是需要指定數(shù)據(jù)庫(kù)引擎為InnoDB,否則不能使用事務(wù)。
spring:
#數(shù)據(jù)庫(kù)配置
datasource:
url: jdbc:mysql://localhost:3306/test?serverTimezone=GMT
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
##validate 加載hibernate時(shí)澈吨,驗(yàn)證創(chuàng)建數(shù)據(jù)庫(kù)表結(jié)構(gòu)
##create 每次加載hibernate把敢,重新創(chuàng)建數(shù)據(jù)庫(kù)表結(jié)構(gòu),這就是導(dǎo)致數(shù)據(jù)庫(kù)表數(shù)據(jù)丟失的原因谅辣。
##create-drop 加載hibernate時(shí)創(chuàng)建修赞,退出是刪除表結(jié)構(gòu)
##update 加載hibernate自動(dòng)更新數(shù)據(jù)庫(kù)結(jié)構(gòu)
##validate 啟動(dòng)時(shí)驗(yàn)證表的結(jié)構(gòu),不會(huì)創(chuàng)建表
##none 啟動(dòng)時(shí)不做任何操作
#jpa配置
jpa:
show-sql: true
properties:
hibernate:
hbm2ddl:
auto: create
# 指定數(shù)據(jù)庫(kù)引擎桑阶,用于使用事務(wù)
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
#端口號(hào)(可不配置柏副,默認(rèn)為8080)
server:
port: 8080
2、創(chuàng)建controller類
- 這里的會(huì)拋出 Data truncation: Data too long for column 'house_name' at row 1(數(shù)據(jù)過(guò)長(zhǎng)異常)蚣录,用于測(cè)試事務(wù)割择。
- @Transactional:打開(kāi)一個(gè)事務(wù)。加在類上所有方法添加事務(wù)萎河,一般不這樣用锨推。
@RestController
public class HouseController {
@Autowired
private HouseRepository houseRepository;
@GetMapping("/test1")
public String test1() {
houseRepository.save(new House("house1", "100平方米"));
houseRepository.save(new House("house2", "100平方米"));
houseRepository.save(new House("house3", "100平方米"));
houseRepository.save(new House("house444444444", "100平方米"));
houseRepository.save(new House("house5", "100平方米"));
return "success";
}
@GetMapping("/test2")
@Transactional
public String test2() {
houseRepository.save(new House("house6", "100平方米"));
houseRepository.save(new House("house7", "100平方米"));
houseRepository.save(new House("house8", "100平方米"));
houseRepository.save(new House("house999999999", "100平方米"));
houseRepository.save(new House("house10", "100平方米"));
return "success";
}
}