Spring框架06-Spring聲明式事務

Spring 聲明式事務的⽀持

編程式事務:在業務代碼中添加事務控制代碼,這樣的事務控制機制就叫作編程式事務    聲明式事務:經過xml或者註解配置的⽅式達到事務控制的⽬的,叫作聲明式事務mysql

5.1事務回顧

5.1.1事務的概念

事務指邏輯上的⼀組操做,組成這組操做的各個單元,要麼所有成功,要麼所有不成功。從⽽確保了數     據的準確與安全。spring

例如:A——B轉賬,對應於以下兩條sql語句:sql

這兩條語句的執⾏,要麼所有成功,要麼所有不成功。數據庫

5.1.2事務的四⼤特性

原⼦性(Atomicity 原⼦性是指事務是⼀個不可分割的⼯做單位,事務中的操做要麼都發⽣,要麼都不發⽣。編程

從操做的⻆度來描述,事務中的各個操做要麼都成功要麼都失敗安全

⼀致性(Consistency)    事務必須使數據庫從⼀個⼀致性狀態變換到另外⼀個⼀致性狀態。例如轉帳前A有1000,B有1000。轉帳後A+B也得是2000。session

⼀致性是從數據的⻆度來講的,(1000,1000) (900,1100),不該該出現(900,1000)mybatis

隔離性(Isolation 事務的隔離性是多個⽤戶併發訪問數據庫時,數據庫爲每⼀個⽤戶開啓的事務, 每一個事務不能被其餘事務的操做數據所⼲擾,多個併發事務之間要相互隔離。併發

⽐如:事務1給員⼯漲⼯資2000,可是事務1還沒有被提交,員⼯發起事務2查詢⼯資,發現⼯資漲了2000 塊錢,讀到了事務1還沒有提交的數據(髒讀)框架

持久性(Durability

持久性是指⼀個事務⼀旦被提交,它對數據庫中數據的改變就是永久性的,接下來即便數據庫發⽣故障     也不該該對其有任何影響。

5.1.3事務的隔離級別

不考慮隔離級別,會出現如下狀況:(如下狀況全是錯誤的),也即爲隔離級別在解決事務併發問題     髒讀:⼀個線程中的事務讀到了另外⼀個線程中未提交的數據。

不可重複讀:⼀個線程中的事務讀到了另外⼀個線程中已經提交的update的數據(先後內容不⼀樣)       場景:

員⼯A發起事務1,查詢⼯資,⼯資爲1w,此時事務1還沒有關閉

財務⼈員發起了事務2,給員⼯A張了2000塊錢,而且提交了事務

員⼯A經過事務1再次發起查詢請求,發現⼯資爲1.2w,原來讀出來1w讀不到了,叫作不可重複讀

虛讀(幻讀):⼀個線程中的事務讀到了另外⼀個線程中已經提交的insert或者delete的數據(先後條數不⼀樣)

場景:

事務1查詢全部⼯資爲1w的員⼯的總數,查詢出來了10個⼈,此時事務還沒有關閉事務2財務⼈員發起,新來員⼯,⼯資1w,向表中插⼊了2條數據,而且提交了事務 事務1再次查詢⼯資爲1w的員⼯個數,發現有12個⼈,⻅了⻤了

數 據 庫 共 定 義 了 四 種 隔 離 級 別 :                                                          Serializable(串⾏化):可避免髒讀、不可重複讀、虛讀狀況的發⽣。(串⾏化) 最⾼Repeatableread(可重複讀):可避免髒讀、不可重複讀狀況的發⽣。(幻讀有可能發⽣) 第⼆該機制下會對要update的⾏進⾏加鎖

Read committed(讀已提交):可避免髒讀狀況發⽣。不可重複讀和幻讀⼀定會發⽣。 第三

Read uncommitted(讀未提交):最低級別,以上狀況均⽆法保證。(讀未提交) 最低

注意:級別依次升⾼,效率依次下降

MySQL的默認隔離級別是:REPEATABLE READ

查詢當前使⽤的隔離級別: select @@tx_isolation;

設置MySQL事務的隔離級別: set session transaction isolation level xxx;(設置的是當前

mysql鏈接會話的,並非永久改變的)

5.1.4事務的傳播⾏爲

事務每每在service層進⾏控制,若是出現service層⽅法A調⽤了另外⼀個service層⽅法B,A和B⽅法本   身都已經被添加了事務控制,那麼A調⽤B的時候,就須要進⾏事務的⼀些協商,這就叫作事務的傳播⾏    爲。

A調⽤B,咱們站在B的⻆度來觀察來定義事務的傳播⾏爲

PROPAGATION_REQUIRED

若是當前沒有事務,就新建⼀個事務,若是已經存在⼀個事務中, 加⼊到這個事務中。這是最常⻅的選擇。

PROPAGATION_SUPPORTS

⽀持當前事務,若是當前沒有事務,就以⾮事務⽅式執⾏。

PROPAGATION_MANDATORY

使⽤當前的事務,若是當前沒有事務,就拋出異常。

PROPAGATION_REQUIRES_NEW

新建事務,若是當前存在事務,把當前事務掛起。

PROPAGATION_NOT_SUPPORTED

以⾮事務⽅式執⾏操做,若是當前存在事務,就把當前事務掛起。

PROPAGATION_NEVER

以⾮事務⽅式執⾏,若是當前存在事務,則拋出異常。

PROPAGATION_NESTED

若是當前存在事務,則在嵌套事務內執⾏。若是當前沒有事務,則執⾏與PROPAGATION_REQUIRED相似的操做。

5.2Spring中事務的API

mybatis: sqlSession.commit(); hibernate: session.commit(); PlatformTransactionManager

做⽤

此接⼝是Spring的事務管理器核⼼接⼝。Spring自己並不⽀持事務實現,只是負責提供標準,應⽤底層

⽀持什麼樣的事務,須要提供具體實現類。此處也是策略模式的具體應⽤。在Spring框架中,也爲咱們   內置了⼀些具體策略,例如:DataSourceTransactionManager, HibernateTransactionManager等等。(和 HibernateTransactionManager事務管理器在 spring-orm-5.1.12.RELEASE.jar中)

SpringJdbcTemplate(數據庫操做⼯具)、Mybatis(mybatis-spring.jar)————> DataSourceTransactionManager

Hibernate框架 ——————> HibernateTransactionManager

DataSourceTransactionManager   歸根結底是橫切邏輯代碼,聲明式事務要作的就是使⽤Aop(動態代理)來將事務控制邏輯織⼊到業務代碼

5.3Spring聲明式事務配置

純xml模式

導⼊jar

xml 配置

基於XML+註解

xml配置

在接⼝、類或者⽅法上添加@Transactional註解

基於純註解

Spring基於註解驅動開發的事務控制配置,只須要把 xml 配置部分改成註解實現。只是須要⼀個注 解 替 換 掉 xml 配 置 ⽂ 件 中 的 <tx:annotation-driven transaction-manager="transactionManager"/>配置。

在 Spring 的配置類上添加 @EnableTransactionManagement 註解便可

相關文章
相關標籤/搜索