欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring聲明式事務(wù)配置使用詳解

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

序章

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

準(zhǔn)備工作

<dependencies>
<!-- 基于Maven依賴傳遞性,導(dǎo)入spring-context依賴即可導(dǎo)入當(dāng)前所需所有jar包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.1</version>
</dependency>
<!-- Spring 持久化層支持jar包 -->
<!-- Spring 在執(zhí)行持久化層操作、與持久化層技術(shù)進(jìn)行整合過程中,需要使用orm、jdbc、tx三個(gè)
jar包 -->
<!-- 導(dǎo)入 orm 包就可以通過 Maven 的依賴傳遞性把其他兩個(gè)也導(dǎo)入 -->
<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ū)動(dòng) -->
<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的配置文件

<!--導(dǎo)入外部屬性文件-->
<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>

聲明式事務(wù)概念

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

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

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

聲明式事務(wù)

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

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

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

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

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

代碼講解

配置 Spring 的配置文件

<!--掃描組件-->
<context:component-scanbase-package="com.atguigu.spring.tx.annotation">
</context:component-scan>
<!--導(dǎo)入外部屬性文件-->
<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'價(jià)格',
`stock`int(10)unsignedDEFAULTNULLCOMMENT'庫存(無符號(hào))',
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'余額(無符號(hào))',
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)建實(shí)現(xiàn)類BookServiceImpl:

測試無事務(wù)情況

②模擬場景

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

假設(shè)用戶id為1的用戶,購買id為1的圖書

用戶余額為50,而圖書價(jià)格為80

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

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

③觀察結(jié)果

因?yàn)闆]有添加事務(wù),圖書的庫存更新了,但是用戶的余額沒有更新

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

加入事務(wù)

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

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

添加事務(wù)注解

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

觀察結(jié)果

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

@Transactional注解標(biāo)識(shí)的位置

@Transactional標(biāo)識(shí)在方法上,咋只會(huì)影響該方法

@Transactional標(biāo)識(shí)的類上,咋會(huì)影響類中所有的方法

事務(wù)屬性:只讀

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

事務(wù)屬性:超時(shí)

事務(wù)在執(zhí)行過程中,有可能因?yàn)橛龅侥承﹩栴},導(dǎo)致程序卡住,從而長時(shí)間占用數(shù)據(jù)庫資源。而長時(shí)間占用資源,大概率是因?yàn)槌绦蜻\(yùn)行出現(xiàn)了問題(可能是Java程序或MySQL數(shù)據(jù)庫或網(wǎng)絡(luò)連接等等)。

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

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

事務(wù)屬性:回滾策略

聲明式事務(wù)默認(rèn)只針對運(yùn)行時(shí)異?;貪L,編譯時(shí)異常不回滾。

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

rollbackFor屬性:需要設(shè)置一個(gè)Class類型的對象

rollbackForClassName屬性:需要設(shè)置一個(gè)字符串類型的全類名

noRollbackFor屬性:需要設(shè)置一個(gè)Class類型的對象

rollbackFor屬性:需要設(shè)置一個(gè)字符串類型的全類名

事務(wù)屬性:事務(wù)隔離級(jí)別

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

隔離級(jí)別一共有四種:

讀未提交:READ UNCOMMITTED

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

讀已提交:READ COMMITTED、

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

可重復(fù)讀:REPEATABLE READ

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

事務(wù)對這個(gè)字段進(jìn)行更新。

串行化:SERIALIZABLE

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

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

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

事務(wù)屬性:事務(wù)傳播行為

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

可以通過@Transactional中的propagation屬性設(shè)置事務(wù)傳播行為

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

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

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

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

相關(guān)文章

  • Java設(shè)計(jì)模式之觀察者模式詳解

    Java設(shè)計(jì)模式之觀察者模式詳解

    這篇文章主要介紹了Java設(shè)計(jì)模式之觀察者模式詳解,對象之間的多對一依賴的一種設(shè)計(jì)方案,被依賴的對象為Subject,依賴的對象為Observer,Subject通知Observer變化,需要的朋友可以參考下
    2023-12-12
  • springBoot server.port=-1的含義說明

    springBoot server.port=-1的含義說明

    這篇文章主要介紹了springBoot server.port=-1的含義說明,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • 基于Java驗(yàn)證jwt token代碼實(shí)例

    基于Java驗(yàn)證jwt token代碼實(shí)例

    這篇文章主要介紹了基于Java驗(yàn)證jwt token代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Java由淺入深細(xì)數(shù)數(shù)組的操作下

    Java由淺入深細(xì)數(shù)數(shù)組的操作下

    數(shù)組對于每一門編程語言來說都是重要的數(shù)據(jù)結(jié)構(gòu)之一,當(dāng)然不同語言對數(shù)組的實(shí)現(xiàn)及處理也不盡相同。Java?語言中提供的數(shù)組是用來存儲(chǔ)固定大小的同類型元素
    2022-04-04
  • 簡單講解Java設(shè)計(jì)模式編程中的單一職責(zé)原則

    簡單講解Java設(shè)計(jì)模式編程中的單一職責(zé)原則

    這篇文章主要介紹了Java設(shè)計(jì)模式編程中的單一職責(zé)原則,這在團(tuán)隊(duì)開發(fā)編寫接口時(shí)經(jīng)常使用這樣的約定,需要的朋友可以參考下
    2016-02-02
  • java實(shí)現(xiàn)學(xué)生宿舍系統(tǒng)

    java實(shí)現(xiàn)學(xué)生宿舍系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)學(xué)生宿舍系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • java按豎線分割的實(shí)現(xiàn)

    java按豎線分割的實(shí)現(xiàn)

    在Java中,我們可以使用split()方法按豎線分割字符串,本文將介紹如何使用Java中的字符串分割方法來按豎線進(jìn)行分割,同時(shí)提供代碼示例來幫助讀者理解,感興趣的可以了解一下
    2024-01-01
  • JAVA WSIMPORT生成WEBSERVICE客戶端401認(rèn)證過程圖解

    JAVA WSIMPORT生成WEBSERVICE客戶端401認(rèn)證過程圖解

    這篇文章主要介紹了JAVA WSIMPORT生成WEBSERVICE客戶端401認(rèn)證過程圖解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • SpringBoot如何優(yōu)雅的整合Swagger Api自動(dòng)生成文檔

    SpringBoot如何優(yōu)雅的整合Swagger Api自動(dòng)生成文檔

    在多人協(xié)作的開發(fā)過程中,API文檔不僅可以減少等待,也能保證開發(fā)的持續(xù)進(jìn)行,這篇文章主要給大家介紹了關(guān)于SpringBoot如何優(yōu)雅的整合Swagger Api自動(dòng)生成文檔的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • JavaWeb?Servlet技術(shù)及其應(yīng)用實(shí)踐

    JavaWeb?Servlet技術(shù)及其應(yīng)用實(shí)踐

    這篇文章主要介紹了JavaWeb?Servlet技術(shù),Servlet指在服務(wù)器端執(zhí)行的一段Java代碼,可以接收用戶的請求和返回給用戶響應(yīng)結(jié)果,感興趣想要詳細(xì)了解可以參考下文
    2023-05-05

最新評(píng)論