javascript
SpringBoot2.0 基础案例(12):基于转账案例,演示事务管理操作
一、事務(wù)管理簡介
1、事務(wù)基本概念
一組業(yè)務(wù)操作ABCD,要么全部成功,要么全部不成功。
2、特性:ACID
原子性:整體
一致性:完成
隔離性:并發(fā)
持久性:結(jié)果
3、隔離問題
臟讀:一個(gè)事務(wù)讀到另一個(gè)事務(wù)沒有提交的數(shù)據(jù)
不可重復(fù)讀:一個(gè)事務(wù)讀到另一個(gè)事務(wù)已提交的數(shù)據(jù)(update)
虛讀(幻讀):一個(gè)事務(wù)讀到另一個(gè)事務(wù)已提交的數(shù)據(jù)(insert)
4、隔離級(jí)別
read uncommitted:讀未提交。
read committed:讀已提交。解決臟讀。
repeatable read:可重復(fù)讀。解決:臟讀、不可重復(fù)讀。
serializable :串行化。都解決,單事務(wù)。
二、Spring管理事務(wù)
1、頂級(jí)接口
1)PlatformTransactionManager
平臺(tái)事務(wù)管理器,spring要管理事務(wù),必須使用事務(wù)管理器進(jìn)行事務(wù)配置時(shí),必須配置事務(wù)管理器。
2)TransactionDefinition
事務(wù)詳情(事務(wù)定義、事務(wù)屬性),spring用于確定事務(wù)具體詳情,
例如:隔離級(jí)別、是否只讀、超時(shí)時(shí)間 等
進(jìn)行事務(wù)配置時(shí),必須配置詳情。spring將配置項(xiàng)封裝到該對(duì)象實(shí)例。
3)TransactionStatus
事務(wù)狀態(tài),spring用于記錄當(dāng)前事務(wù)運(yùn)行狀態(tài)。例如:是否有保存點(diǎn),事務(wù)是否完成。
spring底層根據(jù)狀態(tài)進(jìn)行相應(yīng)操作。
2、事務(wù)狀態(tài)
3、事務(wù)定義
PROPAGATION_REQUIRED , required , 必須 【默認(rèn)值】支持當(dāng)前事務(wù),A如果有事務(wù),B將使用該事務(wù)。如果A沒有事務(wù),B將創(chuàng)建一個(gè)新的事務(wù)。 PROPAGATION_SUPPORTS ,supports ,支持支持當(dāng)前事務(wù),A如果有事務(wù),B將使用該事務(wù)。如果A沒有事務(wù),B將以非事務(wù)執(zhí)行。 PROPAGATION_MANDATORY,mandatory ,強(qiáng)制支持當(dāng)前事務(wù),A如果有事務(wù),B將使用該事務(wù)。如果A沒有事務(wù),B將拋異常。 PROPAGATION_REQUIRES_NEW , requires_new ,必須新的如果A有事務(wù),將A的事務(wù)掛起,B創(chuàng)建一個(gè)新的事務(wù)如果A沒有事務(wù),B創(chuàng)建一個(gè)新的事務(wù) PROPAGATION_NOT_SUPPORTED ,not_supported ,不支持如果A有事務(wù),將A的事務(wù)掛起,B將以非事務(wù)執(zhí)行如果A沒有事務(wù),B將以非事務(wù)執(zhí)行 PROPAGATION_NEVER ,never,從不如果A有事務(wù),B將拋異常如果A沒有事務(wù),B將以非事務(wù)執(zhí)行 PROPAGATION_NESTED ,nested ,嵌套A和B底層采用保存點(diǎn)機(jī)制,形成嵌套事務(wù)。 掌握:PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、PROPAGATION_NESTED三、SpringBoot2.0管理事務(wù)
基于轉(zhuǎn)賬的案例演示,基于druid連接池配置。druid連接池在文章。
SpringBoot2.0 基礎(chǔ)案例(07):集成Druid連接池,配置監(jiān)控界面1、新建轉(zhuǎn)賬表
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、基于事務(wù)手動(dòng)管理器
該配置用于測(cè)試事務(wù)的手動(dòng)管理。
/*** 事物管理器*/ @Bean(name = "transactionManager") public PlatformTransactionManager transactionManager (DruidDataSource dataSource){LOGGER.info("【transactionManager 初始化...】");DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();transactionManager.setDataSource(dataSource);return transactionManager; } /*** 創(chuàng)建事物手動(dòng)管理模板*/ @Bean(name = "transactionTemplate") public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager)LOGGER.info("【transactionTemplate 初始化...】");TransactionTemplate transactionTemplate = new TransactionTemplate() ;transactionTemplate.setTransactionManager(transactionManager);return transactionTemplate; }3、封裝轉(zhuǎn)賬接口
接口方法
public interface AccountService {/*** 匯款*/void out (String outer , Integer money);/*** 收款*/void in (String inner , Integer money); }接口實(shí)現(xiàn)
@Service public class AccountServiceImpl implements AccountService {@Resourceprivate 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、封裝三個(gè)測(cè)試接口
測(cè)試接口
public interface TradeService {/*** 轉(zhuǎn)賬交易:沒有事務(wù)管理*/void trade1(String outer ,String inner ,Integer money);/*** 轉(zhuǎn)賬交易:手動(dòng)管理事務(wù)*/void trade2(String outer ,String inner ,Integer money);/*** 轉(zhuǎn)賬交易:注解管理事務(wù)*/void trade3(String outer ,String inner ,Integer money); }接口實(shí)現(xiàn)
@Service public class TradeServiceImpl implements TradeService {@Resourceprivate AccountService accountService ;@Resourceprivate TransactionTemplate transactionTemplate ;@Overridepublic void trade1(String outer, String inner, Integer money) {accountService.out(outer, money);// 拋出異常int i = 1/0;accountService.in(inner, money);}@Overridepublic 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)@Overridepublic void trade3(String outer, String inner, Integer money) {accountService.out(outer, money);// 拋出異常int i = 1/0;accountService.in(inner, money);} }5、編寫測(cè)試類
@RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = TransactionApplication.class) public class TradeTest {@Resourceprivate TradeService tradeService ;/*** 沒有事務(wù)管理* jack 減少了1000塊錢,但是rose得到1000塊錢* 1 jack 9000* 2 rose 10000*/@Testpublic void testTrade1 (){tradeService.trade1("jack", "rose", 1000);}/*** 手動(dòng)管理事務(wù)* 1 jack 10000* 2 rose 10000*/@Testpublic void testTrade2 (){tradeService.trade2("jack", "rose", 1000);}/*** 注解管理事務(wù)* 1 jack 10000* 2 rose 10000*/@Testpublic void testTrade3 (){tradeService.trade3("jack", "rose", 1000);} }四、源代碼地址
GitHub地址:知了一笑 https://github.com/cicadasmile/spring-boot-base 碼云地址:知了一笑 https://gitee.com/cicadasmile/spring-boot-base
總結(jié)
以上是生活随笔為你收集整理的SpringBoot2.0 基础案例(12):基于转账案例,演示事务管理操作的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux常用命令(第二版) --网络通
- 下一篇: 网络性能测试工具Iperf上手指南