Spring事務(wù)管理的全解析
事務(wù)支持
什么是事務(wù)?
在一個業(yè)務(wù)流程中,需要多條DML(insert、delete、update)語句聯(lián)合才能完成。這些語句必須同時成功或者同時失敗。這樣才能保證數(shù)據(jù)安全。
多條DML同時成功或者同時失敗,叫做事務(wù)。
事務(wù)處理的四個過程
- 開啟事務(wù)
- 執(zhí)行業(yè)務(wù)代碼
- 提交事務(wù)(沒出現(xiàn)異常,提交成功。commit transaction)
- 回滾事務(wù)(出現(xiàn)異常。執(zhí)行回滾事務(wù). rollback transaction)
事務(wù)的四個特性(ACID)
- A原子性:事務(wù)是最小的工作單元,不可分
- C一致性:事務(wù)要么同時成功,要么同時失敗
- I隔離性:事務(wù)與事務(wù)之間保證和互不干擾
- D持久性:持久性是事務(wù)結(jié)束的標(biāo)志。
spring對事務(wù)的支持
spring實現(xiàn)事務(wù)的2種方式:
- 編程式事務(wù):通過編寫代碼的方式來實現(xiàn)事務(wù)管理
- 聲明式事務(wù):基于注解方式和基于xml方式(推薦使用)
spring事務(wù)管理api
spring對事務(wù)的管理是基于aop實現(xiàn)的。所以spring專門針對事務(wù)開發(fā)了一套api,其核心接口如下:PlatformTransactionManager 接口。
聲明式事務(wù)基于注解方式實現(xiàn)
需要配置xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd" >
<!-- 組件掃描-->
<context:component-scan base-package="com.ali" />
<!-- 配置數(shù)據(jù)源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="jdbc:mysql://localhost:3306/bank"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
</bean>
<!-- 配置jdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置事務(wù)管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 開啟事務(wù)注解驅(qū)動器,開啟事務(wù)注解,需要加上tx的命名空間-->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>可以在類和方法上加@Transactional 開啟事務(wù)
- 加在類上表示這個類上的所有方法都開啟事務(wù)
- 加在方法方法上表示只有這個方法開啟事務(wù)
事務(wù)的傳播行為
什么是事務(wù)的傳播行為?
在service種有a()和b()2個方法,a()上有事務(wù),b()上也有事務(wù),當(dāng)a()在執(zhí)行過程中調(diào)用了b(),事務(wù)是如何傳遞的?是合并到一個事務(wù)?還是開啟一個新事務(wù)?這就是事務(wù)的傳播行為。
一共有7種傳播行為:
- REQUIRD:支持當(dāng)前事務(wù),如果不存在就新建一個事務(wù)(默認)【沒有就新建,有就加入】
- SUPPORTS:支持當(dāng)前事務(wù),如果當(dāng)前沒有事務(wù),就以非事務(wù)方式執(zhí)行【有就加入,沒有就不管了】
- MANDATORY:必須運行在一個事務(wù)中,如果當(dāng)前沒有事務(wù)發(fā)生,將拋出異常【有就加入,沒有就拋異?!?/li>
- REQUIRES_NEW:開啟一個新事務(wù),如果一個事務(wù)已經(jīng)存在,則將這個存在的事務(wù)掛起【不管有沒有。直接開啟一個新事務(wù)。新事務(wù)和舊事務(wù)不存在嵌套關(guān)系,舊事務(wù)被掛起了】
- NOT_SUPPORTED:以非事務(wù)方式運行。如果有事務(wù)。則掛起當(dāng)前事務(wù)【不支持事務(wù),存在就掛起】
- NEVER:以非事務(wù)方式運行。如果有事務(wù)。則拋異?!静恢С质聞?wù),存在就拋異?!?/li>
- NESTED:如果當(dāng)前有一個事務(wù)在進行中,則該方法應(yīng)當(dāng)運行在一個嵌套事務(wù)中。被嵌套的事務(wù)可以獨立于外層事務(wù)進行提交或回滾。如果外層事務(wù)不存在。行為就像REQUIRD一樣【有事務(wù)的話,就在這個事務(wù)里嵌套一個完全獨立的事務(wù),嵌套的事務(wù)可以獨立的提交和回滾。沒有事務(wù)就和REQUIRD一樣】
在代碼中設(shè)置事務(wù)的傳播行為:
@Transactional(propagation = Propagation.MANDATORY)
事務(wù)隔離級別
數(shù)據(jù)庫中讀取數(shù)據(jù)存在三大問題:
- 臟讀:讀取到?jīng)]有提交到數(shù)據(jù)庫的數(shù)據(jù)
- 不可重復(fù)讀:在同一個事務(wù)中,第一次和第二次讀取的數(shù)據(jù)不一樣
- 幻讀:讀到的數(shù)據(jù)是假的()
事務(wù)的隔離級別有4個:
- 讀未提交READ_UNCOMMITTED: 存在臟讀、不可重復(fù)讀、幻讀問題
- 讀提交READ_COMMITTED:事務(wù)提交之后才讀到。存在不可重復(fù)讀、幻讀問題
- 可重復(fù)讀REPEATABLE_READ:解決不可重復(fù)讀的問題,存在幻讀問題
- 序列化SERIALIZABLE:解決幻讀問題,事務(wù)排隊執(zhí)行。不支持并發(fā)。
MySQL默認可重復(fù)讀,Oracle默認讀提交
僅在讀的事務(wù)中設(shè)置隔離級別就行,寫的事務(wù)沒必要設(shè)置
代碼中設(shè)置事務(wù)的隔離級別:
@Transactional(isolation = Isolation.DEFAULT)
事務(wù)超時
@Transactional(timeout = 10)
以上代碼設(shè)置事務(wù)超時時間為10s
表示超過10s,如果事務(wù)中所有的DML語句還沒有執(zhí)行完畢的話,最終結(jié)果會回滾。
默認值-1,表示沒有時間限制。
事務(wù)的超時時間值得是哪段時間?
在當(dāng)前事務(wù)中,最后一條DML語句執(zhí)行之前的時間,如果最后一條DML語句后面有很多業(yè)務(wù)邏輯,這些業(yè)務(wù)代碼執(zhí)行的時間不被計入超時時間。
只讀事務(wù)
@Transactional(readOnly = true)
將當(dāng)前事務(wù)設(shè)為只讀事務(wù),在該事務(wù)中只允許執(zhí)行select 語句。
該特性的作用是:啟動spring的優(yōu)化策略。提高select語句的執(zhí)行效率。
設(shè)置哪些異?;貪L事務(wù)
@Transactional(rollbackFor = RuntimeException.class)
表示發(fā)生RuntimeException異?;蛟摦惓5淖宇惍惓2呕貪L
設(shè)置哪些異常不回滾事務(wù)
@Transactional(noRollbackFor = NullPointerException.class)
表示發(fā)生NullPointerException異?;蛟摦惓5淖宇惒换貪L,其他異常才回滾
事務(wù)的全注解式開發(fā)
編寫配置類
@Configuration // 代替xml配置文件
@ComponentScan("com.ali") // 掃描com.ali包下的所有類
@EnableTransactionManagement // 開啟事務(wù)管理
public class Spring6Config {
// @Bean注解用于將方法的返回值注冊為Spring容器中的一個Bean
@Bean(name = "druidDataSource")
public DruidDataSource druidDataSource() {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setUrl("jdbc:mysql://localhost:3306/spring6?useSSL=false&serverTimezone=UTC");
druidDataSource.setUsername("root");
druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
druidDataSource.setPassword("123456");
return druidDataSource;
}
@Bean(name = "transactionManager")
public DataSourceTransactionManager transactionManager(DataSource dataSource) {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
@Bean(name = "jdbcTemplate")
// 該方法的參數(shù)DataSource dataSource會自動從Spring容器中找到類型為DataSource的Bean并注入
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource);
return jdbcTemplate;
}
}使用時和其他方式一樣。
到此這篇關(guān)于Spring事務(wù)管理的文章就介紹到這了,更多相關(guān)spring事務(wù)管理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java?Spring事務(wù)管理超詳細指南
- Spring事務(wù)管理中@Transactional失效的8個常見場景與解決方案
- Spring聲明式事務(wù)管理從原理到實戰(zhàn)示例
- Spring如何使用AOP實現(xiàn)聲明式事務(wù)管理
- SpringBoot整合MongoDB實現(xiàn)事務(wù)管理
- SpringBoot中TransactionTemplate事務(wù)管理的實現(xiàn)
- Spring中的事務(wù)管理及實現(xiàn)方式解析
- Spring?JDBC使用步驟和事務(wù)管理
- Spring聲明式事務(wù)@Transactional注解實現(xiàn)元數(shù)據(jù)驅(qū)動的事務(wù)管理
相關(guān)文章
Java報錯Java.net.SocketTimeoutException的幾種解決方法
在 Java 網(wǎng)絡(luò)編程中,SocketTimeoutException 通常表示在進行網(wǎng)絡(luò)操作時,等待響應(yīng)的時間超過了設(shè)定的超時時間,本文將深入探討 Java.net.SocketTimeoutException 的問題,并為開發(fā)者和環(huán)境配置者提供詳細的解決方案,需要的朋友可以參考下2024-10-10
深入淺析Netty 在 Dubbo 中是如何應(yīng)用的
國內(nèi)知名框架 Dubbo 底層使用的是 Netty 作為網(wǎng)絡(luò)通信,那么內(nèi)部到底是如何使用的呢?今天通過本文給大家詳細講解,對Netty 在 Dubbo中應(yīng)用相關(guān)知識感興趣的朋友跟隨小編一起看看吧2020-05-05
SpringBoot詳解自定義Stater的應(yīng)用
Springboot的出現(xiàn)極大的簡化了開發(fā)人員的配置,而這之中的一大利器便是springboot的starter,starter是springboot的核心組成部分,springboot官方同時也為開發(fā)人員封裝了各種各樣方便好用的starter模塊2022-07-07

