SpringBoot2 基礎案例(12):基於轉賬案例,演示事務管理操作
本文原始碼: GitHub·點這裡 || GitEE·點這裡
一、事務管理簡介
1、事務基本概念
一組業務操作ABCD,要麼全部成功,要麼全部不成功。
2、特性:ACID
原子性:整體
一致性:完成
隔離性:併發
永續性:結果
3、隔離問題
髒讀:一個事務讀到另一個事務沒有提交的資料
不可重複讀:一個事務讀到另一個事務已提交的資料(update)
虛讀(幻讀):一個事務讀到另一個事務已提交的資料(insert)
4、隔離級別
read uncommitted:讀未提交。
read committed:讀已提交。解決髒讀。
repeatable read:可重複讀。解決:髒讀、不可重複讀。
serializable :序列化。都解決,單事務。
二、Spring管理事務
1、頂級介面
1)PlatformTransactionManager
平臺事務管理器,spring要管理事務,必須使用事務管理器進行事務配置時,必須配置事務管理器。
2)TransactionDefinition
事務詳情(事務定義、事務屬性),spring用於確定事務具體詳情,
例如:隔離級別、是否只讀、超時時間 等
進行事務配置時,必須配置詳情。spring將配置項封裝到該物件例項。
3)TransactionStatus
事務狀態,spring用於記錄當前事務執行狀態。例如:是否有儲存點,事務是否完成。
spring底層根據狀態進行相應操作。
2、事務狀態
3、事務定義
PROPAGATION_REQUIRED , required , 必須 【預設值】
支援當前事務,A如果有事務,B將使用該事務。
如果A沒有事務,B將建立一個新的事務。
PROPAGATION_SUPPORTS ,supports ,支援
支援當前事務,A如果有事務,B將使用該事務。
如果A沒有事務,B將以非事務執行。
PROPAGATION_MANDATORY,mandatory ,強制
支援當前事務,A如果有事務,B將使用該事務。
如果A沒有事務,B將拋異常。
PROPAGATION_REQUIRES_NEW , requires_new ,必須新的
如果A有事務,將A的事務掛起,B建立一個新的事務
如果A沒有事務,B建立一個新的事務
PROPAGATION_NOT_SUPPORTED ,not_supported ,不支援
如果A有事務,將A的事務掛起,B將以非事務執行
如果A沒有事務,B將以非事務執行
PROPAGATION_NEVER ,never,從不
如果A有事務,B將拋異常
如果A沒有事務,B將以非事務執行
PROPAGATION_NESTED ,nested ,巢狀
A和B底層採用儲存點機制,形成巢狀事務。
掌握:PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、PROPAGATION_NESTED
三、SpringBoot2 管理事務
基於轉賬的案例演示,基於druid連線池配置。druid連線池在文章。
SpringBoot2.0 基礎案例(07):整合Druid連線池,配置監控介面
1、新建轉賬表
CREATE TABLE account(
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50),
money INT
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO account(username,money) VALUES('jack','10000');
INSERT INTO account(username,money) VALUES('rose','10000');
SELECT * FROM account;
2、基於事務手動管理器
該配置用於測試事務的手動管理。
/**
* 事物管理器
*/
@Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager (DruidDataSource dataSource){
LOGGER.info("【transactionManager 初始化...】");
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
/**
* 建立事物手動管理模板
*/
@Bean(name = "transactionTemplate")
public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager)
LOGGER.info("【transactionTemplate 初始化...】");
TransactionTemplate transactionTemplate = new TransactionTemplate() ;
transactionTemplate.setTransactionManager(transactionManager);
return transactionTemplate;
}
3、封裝轉賬介面
介面方法
public interface AccountService {
/**
* 匯款
*/
void out (String outer , Integer money);
/**
* 收款
*/
void in (String inner , Integer money);
}
介面實現
@Service
public class AccountServiceImpl implements AccountService {
@Resource
private JdbcTemplate jdbcTemplate ;
public void out(String outer, Integer money) {
String sql = "update account set money = money - ? where username = ?";
jdbcTemplate.update(sql, money,outer);
}
public void in(String inner, Integer money) {
String sql = "update account set money = money + ? where username = ?";
jdbcTemplate.update(sql, money,inner);
}
}
4、封裝三個測試介面
測試介面
public interface TradeService {
/**
* 轉賬交易:沒有事務管理
*/
void trade1(String outer ,String inner ,Integer money);
/**
* 轉賬交易:手動管理事務
*/
void trade2(String outer ,String inner ,Integer money);
/**
* 轉賬交易:註解管理事務
*/
void trade3(String outer ,String inner ,Integer money);
}
介面實現
@Service
public class TradeServiceImpl implements TradeService {
@Resource
private AccountService accountService ;
@Resource
private TransactionTemplate transactionTemplate ;
@Override
public void trade1(String outer, String inner, Integer money) {
accountService.out(outer, money);
// 丟擲異常
int i = 1/0;
accountService.in(inner, money);
}
@Override
public void trade2(String outer, String inner, Integer money) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
public void doInTransactionWithoutResult(TransactionStatus arg0) {
accountService.out(outer, money);
// 丟擲異常
int i = 1/0;
accountService.in(inner, money);
}
});
}
@Transactional(value="transactionManager",propagation= Propagation.REQUIRED)
@Override
public void trade3(String outer, String inner, Integer money) {
accountService.out(outer, money);
// 丟擲異常
int i = 1/0;
accountService.in(inner, money);
}
}
5、編寫測試類
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = TransactionApplication.class)
public class TradeTest {
@Resource
private TradeService tradeService ;
/**
* 沒有事務管理
* jack 減少了1000塊錢,但是rose得到1000塊錢
* 1 jack 9000
* 2 rose 10000
*/
@Test
public void testTrade1 (){
tradeService.trade1("jack", "rose", 1000);
}
/**
* 手動管理事務
* 1 jack 10000
* 2 rose 10000
*/
@Test
public void testTrade2 (){
tradeService.trade2("jack", "rose", 1000);
}
/**
* 註解管理事務
* 1 jack 10000
* 2 rose 10000
*/
@Test
public void testTrade3 (){
tradeService.trade3("jack", "rose", 1000);
}
}
四、原始碼地址
GitHub·地址
https://github.com/cicadasmile/spring-boot-base
GitEE·地址
https://gitee.com/cicadasmile/spring-boot-base
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69957347/viewspace-2672209/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SpringBoot2 基礎案例(13):基於Cache註解,管理Redis快取Spring BootRedis快取
- SpringBoot2 基礎案例(08):整合Redis資料庫,實現快取管理Spring BootRedis資料庫快取
- 服務案例|基於IT事件管理,提升業務連續性事件
- SpringBoot2 基礎案例(09):整合JPA持久層框架,簡化資料庫操作Spring Boot框架資料庫
- SQL Server 表的管理_關於事務操作的詳解(案例程式碼)SQLServer
- Java基礎經典案例Java
- VUE的基礎案例1Vue
- SpringBoot2 基礎案例(06):引入JdbcTemplate,和多資料來源配置Spring BootJDBC
- 基於微服務框架Micronaut和Eventuate Tram實現分散式事務的開源案例微服務框架分散式
- SpringBoot2 基礎案例(07):整合Druid連線池,配置監控介面Spring BootUI
- SQL的基礎查詢案例SQL
- 基礎爬蟲案例實戰爬蟲
- mysql基礎_事務MySql
- 基於Java的微服務架構原始碼案例AbixenJava微服務架構原始碼
- python 程式設計基礎案例Python程式設計
- Mysql基礎 --- 索引+事務MySql索引
- 基於 go + xpath 爬蟲小案例Go爬蟲
- 基於Spring中的事務管理機制Spring
- 正規表示式 基礎+使用案例解析
- HarmonyOS-基礎之聯絡人案例
- MyBatis基於xml檔案的 CURD案例MyBatisXML
- 第三代微服務架構:基於 Go 的部落格微服務實戰案例,支援分散式事務微服務架構Go分散式
- flutter 案例 (一): 搭建介面基礎導航框架Flutter框架
- Mysql儲存過程基礎(案例+程式碼)MySql儲存過程
- Java基礎-處理json字串解析案例JavaJSON字串
- 前端基礎之原生js事件繫結案例前端JS事件
- 基於graphql的微服務基礎框架微服務框架
- MySQL基礎架構和事務MySql架構
- 基於Dtm分散式事務管理的php客戶端分散式PHP客戶端
- 基於 golang 的支付寶支付小案例Golang
- Spring Boot 2.x基礎教程:事務管理入門Spring Boot
- JS 基礎篇(策略模式-表單驗證案例)JS模式
- 《驚奇劍士》:0基礎做遊戲”的完美案例遊戲
- Hadoop之MapReduce2基礎梳理及案例Hadoop
- 通過Spring Boot,Spring Cloud Gateway構建基於Consul叢集的微服務案例演示 – Piotr的TechBlogSpring BootCloudGateway微服務
- 透過Spring Boot,Spring Cloud Gateway構建基於Consul叢集的微服務案例演示 – Piotr的TechBlogSpring BootCloudGateway微服務
- MySQL基於事務的ReplcaitonMySqlAI
- git的工作管理和基礎操作Git