最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring聲明式事務配置使用詳解

 更新時間:2022年08月31日 08:44:56   作者:一個風輕云淡  
這篇文章主要介紹了在spring注解中,使用聲明式事務,需要用到兩個核心的注解:@Transactional注解和@EnableTransactionManagement注解。將@Transactional注解加在方法上,@EnableTransactionManagement注解加在配置類上

序章

Spring 框架對 JDBC 進行封裝,使用 JdbcTemplate 方便實現(xiàn)對數(shù)據(jù)庫操作

準備工作

<dependencies>
<!-- 基于Maven依賴傳遞性,導入spring-context依賴即可導入當前所需所有jar包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.1</version>
</dependency>
<!-- Spring 持久化層支持jar包 -->
<!-- Spring 在執(zhí)行持久化層操作、與持久化層技術(shù)進行整合過程中,需要使用orm、jdbc、tx三個
jar包 -->
<!-- 導入 orm 包就可以通過 Maven 的依賴傳遞性把其他兩個也導入 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.3.1</version>
</dependency>
<!-- Spring 測試相關(guān) -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.1</version>
</dependency>
<!-- junit測試 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- MySQL驅(qū)動 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<!-- 數(shù)據(jù)源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.31</version>
</dependency>
</dependencies>

創(chuàng)建jdbc.properties

jdbc.user=root
jdbc.password=atguigu
jdbc.url=jdbc:mysql://localhost:3306/ssm
jdbc.driver=com.mysql.cj.jdbc.Driver

配置Spring的配置文件

<!--導入外部屬性文件-->
<context:property-placeholderlocation="classpath:jdbc.properties"/>
<!--配置數(shù)據(jù)源-->
<beanid="druidDataSource"class="com.alibaba.druid.pool.DruidDataSource"> 
 <propertyname="url"value="${atguigu.url}"/>
  <propertyname="driverClassName"value="${atguigu.driver}"/>
  <propertyname="username"value="${atguigu.username}"/>
  <propertyname="password"value="${atguigu.password}"/>
</bean>
<!--配置JdbcTemplate-->
<beanid="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate">  <!--裝配數(shù)據(jù)源-->
  <propertyname="dataSource"ref="druidDataSource"/>
</bean>

聲明式事務概念

編程式的實現(xiàn)方式存在缺陷:

細節(jié)沒有被屏蔽:具體操作過程中,所有細節(jié)都需要程序員自己來完成,比較繁瑣。

代碼復用性不高:如果沒有有效抽取出來,每次實現(xiàn)功能都需要自己編寫代碼,代碼就沒有得到復 用。

聲明式事務

既然事務控制的代碼有規(guī)律可循,代碼的結(jié)構(gòu)基本是確定的,所以框架就可以將固定模式的代碼抽取出來,進行相關(guān)的封裝。

封裝起來后,我們只需要在配置文件中進行簡單的配置即可完成操作。

好處1:提高開發(fā)效率

好處2:消除了冗余的代碼

好處3:框架會綜合考慮相關(guān)領域中在實際開發(fā)環(huán)境下有可能遇到的各種問題,進行了健壯性、性 能等各個方面的優(yōu)化

代碼講解

配置 Spring 的配置文件

<!--掃描組件-->
<context:component-scanbase-package="com.atguigu.spring.tx.annotation">
</context:component-scan>
<!--導入外部屬性文件-->
<context:property-placeholderlocation="classpath:jdbc.properties"/>
<!--配置數(shù)據(jù)源-->
<beanid="druidDataSource"class="com.alibaba.druid.pool.DruidDataSource">  
<propertyname="url"value="${jdbc.url}"/>
  <propertyname="driverClassName"value="${jdbc.driver}"/>
  <propertyname="username"value="${jdbc.username}"/>
  <propertyname="password"value="${jdbc.password}"/>
</bean>
<!--配置JdbcTemplate-->
<beanid="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate">
  <!--裝配數(shù)據(jù)源-->
  <propertyname="dataSource"ref="druidDataSource"/>
</bean>

創(chuàng)建表

REATETABLE`t_book`(
book_id`int(11)NOTNULLAUTO_INCREMENTCOMMENT'主鍵',
`book_name`varchar(20)DEFAULTNULLCOMMENT'圖書名稱',
`price`int(11)DEFAULTNULLCOMMENT'價格',
`stock`int(10)unsignedDEFAULTNULLCOMMENT'庫存(無符號)',
PRIMARYKEY(`book_id`)
)ENGINE=InnoDBAUTO_INCREMENT=3DEFAULTCHARSET=utf8;
insert into`t_book`(`book_id`,`book_name`,`price`,`stock`)values(1,'斗破蒼穹',80,100),(2,'斗羅大陸',50,100);
CREATETABLE`t_user`(
`user_id`int(11)NOTNULLAUTO_INCREMENTCOMMENT'主鍵',
`username`varchar(20)DEFAULTNULLCOMMENT'用戶名',
`balance`int(10)unsignedDEFAULTNULLCOMMENT'余額(無符號)',
PRIMARYKEY(`user_id`)
)ENGINE=InnoDBAUTO_INCREMENT=2DEFAULTCHARSET=utf8;
insert into`t_user`(`user_id`,`username`,`balance`)values(1,'admin',50);

創(chuàng)建組件

創(chuàng)建BookController:

@Controller
public class BookController {
    @Autowired
    private BookService bookService;
    public void buyBook(Integer bookId, Integer userId){
    bookService.buyBook(bookId, userId);
    }
}

創(chuàng)建接口BookService:

public interface BookService {    
void buyBook(Integer bookId, Integer userId);
}

創(chuàng)建實現(xiàn)類BookServiceImpl:

測試無事務情況

②模擬場景

用戶購買圖書,先查詢圖書的價格,再更新圖書的庫存和用戶的余額

假設用戶id為1的用戶,購買id為1的圖書

用戶余額為50,而圖書價格為80

購買圖書之后,用戶的余額為-30,數(shù)據(jù)庫中余額字段設置了無符號,因此無法將-30插入到余額字段

此時執(zhí)行sql語句會拋出SQLException

③觀察結(jié)果

因為沒有添加事務,圖書的庫存更新了,但是用戶的余額沒有更新

顯然這樣的結(jié)果是錯誤的,購買圖書是一個完整的功能,更新庫存和更新余額要么都成功要么都失敗

加入事務

<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--
開啟事務的注解驅(qū)動
通過注解@Transactional所標識的方法或標識的類中所有的方法,都會被事務管理器管理事務
-->
<!-- transaction-manager屬性的默認值是transactionManager,如果事務管理器bean的id正好就
是這個默認值,則可以省略這個屬性 -->
<tx:annotation-driven transaction-manager="transactionManager" />

注意:導入的名稱空間需要 tx 結(jié)尾的那個。

添加事務注解

因為service層表示業(yè)務邏輯層,一個方法表示一個完成的功能,因此處理事務一般在service層處理在BookServiceImpl的buybook()添加注解@Transactiona

觀察結(jié)果

由于使用了Spring的聲明式事務,更新庫存和更新余額都沒有執(zhí)行

@Transactional注解標識的位置

@Transactional標識在方法上,咋只會影響該方法

@Transactional標識的類上,咋會影響類中所有的方法

事務屬性:只讀

對一個查詢操作來說,如果我們把它設置成只讀,就能夠明確告訴數(shù)據(jù)庫,這個操作不涉及寫操作。這樣數(shù)據(jù)庫就能夠針對查詢操作來進行優(yōu)化。

事務屬性:超時

事務在執(zhí)行過程中,有可能因為遇到某些問題,導致程序卡住,從而長時間占用數(shù)據(jù)庫資源。而長時間占用資源,大概率是因為程序運行出現(xiàn)了問題(可能是Java程序或MySQL數(shù)據(jù)庫或網(wǎng)絡連接等等)。

此時這個很可能出問題的程序應該被回滾,撤銷它已做的操作,事務結(jié)束,把資源讓出來,讓其他正常程序可以執(zhí)行

概括來說就是一句話:超時回滾,釋放資源。

事務屬性:回滾策略

聲明式事務默認只針對運行時異?;貪L,編譯時異常不回滾。

可以通過@Transactional中相關(guān)屬性設置回滾策略

rollbackFor屬性:需要設置一個Class類型的對象

rollbackForClassName屬性:需要設置一個字符串類型的全類名

noRollbackFor屬性:需要設置一個Class類型的對象

rollbackFor屬性:需要設置一個字符串類型的全類名

事務屬性:事務隔離級別

數(shù)據(jù)庫系統(tǒng)必須具有隔離并發(fā)運行各個事務的能力,使它們不會相互影響,避免各種并發(fā)問題。一個事務與其他事務隔離的程度稱為隔離級別。SQL標準中規(guī)定了多種事務隔離級別,不同隔離級別對應不同的干擾程度,隔離級別越高,數(shù)據(jù)一致性就越好,但并發(fā)性越弱。

隔離級別一共有四種:

讀未提交:READ UNCOMMITTED

允許Transaction01讀取Transaction02未提交的修改。

讀已提交:READ COMMITTED、

要求Transaction01只能讀取Transaction02已提交的修改。

可重復讀:REPEATABLE READ

確保Transaction01可以多次從一個字段中讀取到相同的值,即Transaction01執(zhí)行期間禁止其它

事務對這個字段進行更新。

串行化:SERIALIZABLE

確保Transaction01可以多次從一個表中讀取到相同的行,在Transaction01執(zhí)行期間,禁止其它

事務對這個表進行添加、更新、刪除操作??梢员苊馊魏尾l(fā)問題,但性能十分低下。

@Transactional(isolation = Isolation.DEFAULT)//使用數(shù)據(jù)庫默認的隔離級別
@Transactional(isolation = Isolation.READ_UNCOMMITTED)//讀未提交
@Transactional(isolation = Isolation.READ_COMMITTED)//讀已提交
@Transactional(isolation = Isolation.REPEATABLE_READ)//可重復讀
@Transactional(isolation = Isolation.SERIALIZABLE)//串行化

事務屬性:事務傳播行為

當事務方法被另一個事務方法調(diào)用時,必須指定事務應該如何傳播。例如:方法可能繼續(xù)在現(xiàn)有事務中運行,也可能開啟一個新事務,并在自己的事務中運行。

可以通過@Transactional中的propagation屬性設置事務傳播行為

修改BookServiceImpl中buyBook()上,注解@Transactional的propagation屬性

@Transactional(propagation = Propagation.REQUIRED),默認情況,表示如果當前線程上有已經(jīng)開啟的事務可用,那么就在這個事務中運行。經(jīng)過觀察,購買圖書的方法buyBook()在checkout()中被調(diào)用,checkout()上有事務注解,因此在此事務中執(zhí)行。所購買的兩本圖書的價格為80和50,而用戶的余額為100,因此在購買第二本圖書時余額不足失敗,導致整個checkout()回滾,即只要有一本書買不了,就都買不了

@Transactional(propagation = Propagation.REQUIRES_NEW),表示不管當前線程上是否有已經(jīng)開啟的事務,都要開啟新事務。同樣的場景,每次購買圖書都是在buyBook()的事務中執(zhí)行,因此第一本圖書購買成功,事務結(jié)束,第二本圖書購買失敗,只在第二次的buyBook()中回滾,購買第一本圖書不受影響,即能買幾本就買幾本

到此這篇關(guān)于Spring聲明式事務配置使用詳解的文章就介紹到這了,更多相關(guān)Spring聲明式事務內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot路徑映射實現(xiàn)過程圖解

    SpringBoot路徑映射實現(xiàn)過程圖解

    這篇文章主要介紹了SpringBoot路徑映射實現(xiàn)過程圖解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • java 實現(xiàn)websocket的兩種方式實例詳解

    java 實現(xiàn)websocket的兩種方式實例詳解

    這篇文章主要介紹了java 實現(xiàn)websocket的兩種方式實例詳解,一種使用tomcat的websocket實現(xiàn),一種使用spring的websocket,本文通過代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2018-07-07
  • MyBatis 中使用 Mapper 簡化代碼的方法

    MyBatis 中使用 Mapper 簡化代碼的方法

    這篇文章主要介紹了MyBatis 中使用 Mapper 簡化代碼的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • SpringBoot如何動態(tài)修改Scheduled(系統(tǒng)啟動默認執(zhí)行,動態(tài)修改)

    SpringBoot如何動態(tài)修改Scheduled(系統(tǒng)啟動默認執(zhí)行,動態(tài)修改)

    這篇文章主要介紹了SpringBoot如何動態(tài)修改Scheduled(系統(tǒng)啟動默認執(zhí)行,動態(tài)修改)的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Spring中的PathVariable注釋解析

    Spring中的PathVariable注釋解析

    這篇文章主要介紹了Spring中的PathVariable注釋用法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Spring?Framework六種常見設計模式

    Spring?Framework六種常見設計模式

    設計模式是軟件開發(fā)的重要組成部分,本文借助spring來講解這個框架的設計模式,通過本文我們探討了spring如何利用這些模式來提供這些豐富的功能,對本文感興趣的朋友跟隨小編一起看看吧
    2023-06-06
  • springboot整合druid連接池的步驟

    springboot整合druid連接池的步驟

    這篇文章主要介紹了springboot整合druid連接池的步驟,幫助大家更好的理解和學習springboot框架,感興趣的朋友可以了解下
    2020-11-11
  • Redis實現(xiàn)商品秒殺功能頁面流程

    Redis實現(xiàn)商品秒殺功能頁面流程

    這篇文章主要介紹了Redis實現(xiàn)商品秒殺功能的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-09-09
  • 詳解Spring Cloud Zuul 服務網(wǎng)關(guān)

    詳解Spring Cloud Zuul 服務網(wǎng)關(guān)

    本篇文章主要介紹了詳解Spring Cloud Zuul 服務網(wǎng)關(guān),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • Java中的鎖與鎖的狀態(tài)升級詳細解讀

    Java中的鎖與鎖的狀態(tài)升級詳細解讀

    這篇文章主要介紹了Java中的鎖與鎖的狀態(tài)升級詳細解讀,Java 1.6以后官方針對鎖的優(yōu)化,主要是增加了兩種新的鎖:偏向鎖和輕量級鎖,再加上本身重量級鎖,那么鎖基本上可以大致分為這三種,它們之間的區(qū)別主要是體現(xiàn)在等待時間上面,需要的朋友可以參考下
    2024-01-01

最新評論

海淀区| 嘉义县| 离岛区| 大荔县| 东方市| 武乡县| 娱乐| 莲花县| 都江堰市| 五华县| 轮台县| 门源| 凌海市| 兰考县| 鹤峰县| 洪雅县| 迭部县| 成安县| 静海县| 山丹县| 张掖市| 犍为县| 大悟县| 廊坊市| 讷河市| 塔城市| 钟祥市| 隆林| 迭部县| 惠水县| 广水市| 文安县| 龙州县| 吕梁市| 大姚县| 梅州市| 建宁县| 拜城县| 汾西县| 扶沟县| 静宁县|