Spring中@Transactional注解的屬性說明
1 .添加位置
1)接口實(shí)現(xiàn)類或接口實(shí)現(xiàn)方法上,而不是接口類中。
2)訪問權(quán)限:public 的方法才起作用。@Transactional 注解應(yīng)該只被應(yīng)用到 public 方法上,這是由 Spring AOP 的本質(zhì)決定的。 系統(tǒng)設(shè)計(jì):最好將標(biāo)簽放置在需要進(jìn)行事務(wù)管理的方法上,而不是放在所有接口實(shí)現(xiàn)類上:因?yàn)橹蛔x的接口就不需要事務(wù)管理,由于配置了@Transactional就需要AOP攔截及事務(wù)的處理,可能影響系統(tǒng)性能。如果想放在實(shí)現(xiàn)類上,可以加一個readOnly=true,忽略那些不需要事務(wù)的方法,比如讀取數(shù)據(jù)。
3)錯誤使用:
1.接口中A、B兩個方法,A無@Transactional標(biāo)簽,B有,上層通過A間接調(diào)用B,此時(shí)事務(wù)不生效。
2.接口中異常(運(yùn)行時(shí)異常)被捕獲而沒有被拋出。
默認(rèn)配置下,spring 只有在拋出的異常為運(yùn)行時(shí) unchecked 異常時(shí)才回滾該事務(wù),
也就是拋出的異常為RuntimeException 的子類(Errors也會導(dǎo)致事務(wù)回滾),而拋出 checked 異常則不會導(dǎo)致事務(wù)回滾 ??赏ㄟ^ @Transactional rollbackFor進(jìn)行配置。
3.多線程下事務(wù)管理因?yàn)榫€程不屬于 spring 托管,故線程不能夠默認(rèn)使用 spring 的事務(wù), 也不能獲取spring 注入的 bean 。
在被 spring 聲明式事務(wù)管理的方法內(nèi)開啟多線程,多線程內(nèi)的方法不被事務(wù)控制。
一個使用了@Transactional 的方法,如果方法內(nèi)包含多線程的使用,方法內(nèi)部出現(xiàn)異常, 不會回滾線程中調(diào)用方法的事務(wù)。
2.聲明式事務(wù)管理實(shí)現(xiàn)方式
基于 tx 和 aop 名字空間的 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:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:task="http://www.springframework.org/schema/task" xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-4.1.xsd">
<bean name="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="shardingDataSource"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
// MyBatis 自動參與到 spring 事務(wù)管理中,無需額外配置,
只要 org.mybatis.spring.SqlSessionFactoryBean 引用的數(shù)據(jù)源與
DataSourceTransactionManager 引用的數(shù)據(jù)源一致即可,否則事務(wù)管理會不起作用。
// <annotation-driven> 標(biāo)簽的聲明,
是在 Spring 內(nèi)部啟用 @Transactional 來進(jìn)行事務(wù)管理,使用 @Transactional 前需要配置。
3. @Transactional注解
@Transactional 實(shí)質(zhì)是使用了 JDBC 的事務(wù)來進(jìn)行事務(wù)控制的 @Transactional 基于 Spring 的動態(tài)代理的機(jī)制
@Transactional 實(shí)現(xiàn)原理:
1) 事務(wù)開始時(shí),通過AOP機(jī)制,生成一個代理connection對象, 并將其放入 DataSource 實(shí)例的某個與 DataSourceTransactionManager 相關(guān)的某處容器中。
在接下來的整個事務(wù)中,客戶代碼都應(yīng)該使用該 connection 連接數(shù)據(jù)庫, 執(zhí)行所有數(shù)據(jù)庫命令。
[不使用該 connection 連接數(shù)據(jù)庫執(zhí)行的數(shù)據(jù)庫命令,在本事務(wù)回滾的時(shí)候得不到回滾]
(物理連接 connection 邏輯上新建一個會話session; DataSource 與 TransactionManager 配置相同的數(shù)據(jù)源)
2) 事務(wù)結(jié)束時(shí),回滾在第1步驟中得到的代理 connection 對象上執(zhí)行的數(shù)據(jù)庫命令,然后關(guān)閉該代理 connection 對象。
(事務(wù)結(jié)束后,回滾操作不會對已執(zhí)行完畢的SQL操作命令起作用)
4. @Transactional 注解的屬性介紹
下面分別介紹一下 @Transactional 的幾個屬性。
value 和 transactionManager 屬性 它們兩個是一樣的意思。當(dāng)配置了多個事務(wù)管理器時(shí),可以使用該屬性指定選擇哪個事務(wù)管理器。
propagation 屬性 事務(wù)的傳播行為,默認(rèn)值為 Propagation.REQUIRED。
可選的值有:
- Propagation.REQUIRED 如果當(dāng)前存在事務(wù),則加入該事務(wù),如果當(dāng)前不存在事務(wù),則創(chuàng)建一個新的事務(wù)。
- Propagation.SUPPORTS 如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前不存在事務(wù),則以非事務(wù)的方式繼續(xù)運(yùn)行。
- Propagation.MANDATORY 如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前不存在事務(wù),則拋出異常。
- Propagation.REQUIRES_NEW 重新創(chuàng)建一個新的事務(wù),如果當(dāng)前存在事務(wù),暫停當(dāng)前的事務(wù)。
- Propagation.NOT_SUPPORTED 以非事務(wù)的方式運(yùn)行,如果當(dāng)前存在事務(wù),暫停當(dāng)前的事務(wù)。
- Propagation.NEVER 以非事務(wù)的方式運(yùn)行,如果當(dāng)前存在事務(wù),則拋出異常。
- Propagation.NESTED 和 Propagation.REQUIRED 效果一樣。
這些概念理解起來實(shí)在是有點(diǎn)兒抽象,后文會用代碼示例解釋說明。
isolation 屬性 事務(wù)的隔離級別,默認(rèn)值為 Isolation.DEFAULT。
可選的值有:
- Isolation.DEFAULT
使用底層數(shù)據(jù)庫默認(rèn)的隔離級別。
Isolation.READ_UNCOMMITTED Isolation.READ_COMMITTED Isolation.REPEATABLE_READ Isolation.SERIALIZABLE timeout 屬性 事務(wù)的超時(shí)時(shí)間,默認(rèn)值為-1。如果超過該時(shí)間限制但事務(wù)還沒有完成,則自動回滾事務(wù)。
- readOnly 屬性 指定事務(wù)是否為只讀事務(wù),默認(rèn)值為 false;為了忽略那些不需要事務(wù)的方法,比如讀取數(shù)據(jù),可以設(shè)置 read-only 為 true。
- rollbackFor 屬性 用于指定能夠觸發(fā)事務(wù)回滾的異常類型,可以指定多個異常類型。
- noRollbackFor 屬性 拋出指定的異常類型,不回滾事務(wù),也可以指定多個異常類型。
5. 注解方式的事務(wù)使用注意事項(xiàng)
正確的設(shè)置@Transactional 的 rollbackFor 屬性 默認(rèn)情況下,如果在事務(wù)中拋出了**未檢查異常(繼承自 RuntimeException 的異常)**或者 Error,則 Spring 將回滾事務(wù);除此之外,Spring 不會回滾事務(wù)。
如果在事務(wù)中拋出其他類型的異常,并期望 Spring 能夠回滾事務(wù),可以指定** rollbackFor**。例:
@Transactional(propagation= Propagation.REQUIRED,rollbackFor= MyException.class)
通過分析 Spring 源碼可以知道,若在目標(biāo)方法中拋出的異常是 rollbackFor 指定的異常的子類,事務(wù)同樣會回滾。
到此這篇關(guān)于Spring中@Transactional注解的屬性說明的文章就介紹到這了,更多相關(guān)@Transactional注解的屬性內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java 實(shí)戰(zhàn)項(xiàng)目之疫情人員流動管理系統(tǒng)詳解
讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用Java實(shí)現(xiàn)一個疫情人員流動管理系統(tǒng),大家可以在過程中查缺補(bǔ)漏,提升水平2021-11-11
使用Sentinel滑動窗口實(shí)現(xiàn)限流和降級
Sentinel 是一個開源的高可用性、高擴(kuò)展性的實(shí)時(shí)流量控制框架,它可以用于保護(hù)服務(wù)穩(wěn)定性,防止系統(tǒng)因?yàn)榱髁窟^大而崩潰,這篇文章我們所介紹的是滑動窗口,它是 Sentinel 實(shí)現(xiàn)限流和降級的重要組件之一,感興趣的同學(xué)跟著小編來看看吧2023-09-09
SpringBoot環(huán)境下服務(wù)端向客戶端主動推送數(shù)據(jù)的幾種常見方式
在傳統(tǒng)的 HTTP 請求-響應(yīng)模型中,客戶端需要主動發(fā)起請求,服務(wù)端才能返回?cái)?shù)據(jù),然而,在某些場景下,我們希望服務(wù)端能夠主動向客戶端推送數(shù)據(jù),本文將詳細(xì)介紹在 Spring Boot 環(huán)境下實(shí)現(xiàn)服務(wù)端向客戶端主動推送數(shù)據(jù)的幾種常見方式,并比較它們的優(yōu)缺點(diǎn)和適用場景2025-07-07
Java ExecutorServic線程池異步實(shí)現(xiàn)流程
這篇文章主要介紹了Java ExecutorServic線程池異步實(shí)現(xiàn)流程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12
詳解Spring Boot + Mybatis 實(shí)現(xiàn)動態(tài)數(shù)據(jù)源
這篇文章主要介紹了Spring Boot + Mybatis 實(shí)現(xiàn)動態(tài)數(shù)據(jù)源,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
java實(shí)現(xiàn)微信企業(yè)付款到個人
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)微信企業(yè)付款到個人功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-10-10
spring boot+ redis 接口訪問頻率限制的實(shí)現(xiàn)
這篇文章主要介紹了spring boot+ redis 接口訪問頻率限制的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01

