一、spring事務管理
1、 什么是事務
事務(Transaction)是多個操作數據庫的步驟(CRUD)的集合,是並發控制的單位,是用戶定義的一個操作序列。這些操作要么都做,要么都不做,是一個不可分割的工作單位。達到保持數據完整性的作用。
2、 事務特點
1) 原子性
一個事務所有對數據庫操作是一個最小單位,不可細分;要么執行,要么不執行
2) 隔離性
事務之間可以同時執行,不會互相干擾,是隔離的
3) 一致性
事務執行成功數據庫變更,事務執行失敗數據庫不變更,即事務一致性
4) 持久性
事務執行成功,之后的結果是持久的,一直保持
3、 事務配置方式
1) 編程式事務
編程式事務指的是通過編碼方式實現事務,需要配置文件添加配置,並且在編碼中也需要配置,現在使用越來越少
2) 聲明式事務
建立在AOP之上的。對方法前后進行攔截,然后在目標方法開始之前創建或者加入一個事務,在執行完目標方法之后根據執行情況提交或者回滾事務;聲明式事務配置一般有五種(abcde),兩種配置方式較為常用:我喜歡用第一種
a) 使用AOP的方式實現事務配置
i. aop:pointcut標簽配置參與事務的類,由於是在Service中進行數據庫業務操作,配的應該是包含那些作為事務的方法的Service類。
首先應該特別注意的是id的命名,同樣由於每個模塊都有自己事務切面,所以我覺得初步的命名規則因為 all+模塊名+ServiceMethod。而且每個模塊之間不同之處還在於以下一句:
expression="execution(* com.test.testAda.test.model.service.*.*(..))"
其中第一個*代表返回值,第二*代表service下子包,第三個*代表方法名,“(..)”代表方法參數。
ii. aop:advisor標簽主要將事務屬性配置和開啟事務類進行關聯
iii. tx:attributes標簽主要是配置事務的方法屬性類型,name=add*中表示事務中所有以add開頭的方法。
b) 注解式配置
i. Spring-mybatis
ii. Spring-hibernata
iii. 注意@Transaction注解的使用
這個注解只能使用在public方法上,別的不會報錯,但是沒有效果;如果這個注解放在類上,類里面的所有public方法都會有效。
iv. 全注解的使用方式
v. 注解中屬性詳解
Propagation是傳播屬性,REQUIRED代表使用當前開啟事務;rollbackFor=Exception.class代表出現異常回滾,可以指定多個異常;
Timeout =1 事務的超時性;
Isolation代表事務隔離級別,上面的是默認;
配置readOnly=true表示當前事務為只讀事務,如果為false為可讀寫,默認是false。
vi. 注解位置
注解最好放在具體的類或者方法上,不要放在接口上,因為注解不具有繼承性,所以如果讀取不到注解信息,將不會讀取到相應對象二進行事務配置。
c) 每個bean都有一個代理
https://blog.csdn.net/hjm4702192/article/details/17277669
d) 所有bean共享一個代理基類
https://blog.csdn.net/hjm4702192/article/details/17277669
e) 使用攔截器
https://blog.csdn.net/hjm4702192/article/details/17277669
4、 事務隔離級別
事務隔離級別指的是多個並發事務之間的隔離程度
1) ISOLATION_DEFAULT
此種隔離級別是事務管理默認配置的,使用數據庫的默認隔離級別,上面的配置中就是使用此種級別,下面的四種級別與jdbc的相對應。
2) ISOLATION_READ_UNCOMMITTED
未提交讀。允許其他事務可以看到本事務未提交的數據,可造成臟讀、幻讀和不可重復讀
3) ISOLATION_READ_COMMITTED
提交讀。其他事務只能讀取到本事務提交后的數據,本事務不提交,其他事務無法讀取到本事務數據,可防止臟讀,可能出現幻讀和不可重復讀
4) ISOLATION_REPEATABLE_READ
可重復度。保證事務不提交就不會讀取到其數據,防止臟讀和不可重復讀,可能發生幻讀。
5) ISOLATION_SERIALIZABLE
可串行化。犧牲效率順序執行事物,如果事物執行異常,其他事務阻塞。防止臟讀,幻讀和不可重復。
5、 事務傳播屬性
1) PROPAGATION_REQUIRED
使用當前事務,如果當前無事務,新建一個事務
2) PROPAGATION_SUPPORTS
使用當前事務,如果當前無事務,使用非事務方式執行
3) PROPAGATION_MANDATORY
使用當前事務,如果當前無事務,拋出異常
4) PROPAGATION_REQUIRES_NEW
每次執行新建事務,如果當前存在事務,將當前事務掛起
5) PROPAGATION_NOT_SUPPORTED
以非事務方式執行,如果當前存在事務,將當前事務掛起
6) PROPAGATION_NEVER
以非事務方式執行,如果當前存在事務,拋出異常
7) PROPAGATION_NESTED
嵌套類事務,如果當前存在事務,則在當前事務內新建事務並執行,如果當前無事務,與第一條同樣方式執行
二、數據庫隔離級別
1、未提交讀
(Read Uncommitted):允許臟讀,也就是可能讀取到其他會話中未提交事務修改的數據
2、提交讀
(Read Committed):只能讀取到已經提交的數據。Oracle等多數數據庫默認都是該級別 (不重復讀)
3、可重復度
(Repeated Read):可重復讀。在同一個事務內的查詢都是事務開始時刻一致的,InnoDB默認級別。在SQL標准中,該隔離級別消除了不可重復讀,但是還存在幻象讀
4、可串行化
(Serializable):完全串行化的讀,每次讀都需要獲得表級共享鎖,讀寫相互都會阻塞
三、數據異常
1、臟讀
A事務正在添加zhangsan信息,但是還沒提交,數據庫就已經能讀取到張三信息。
2、幻讀
多個事務同時修改同一條記錄,事務之間不知道彼此存在,當事務提交之后,后面的事務修改的數據將會覆蓋前事務,前一個事務就像發生幻覺一樣
例如:同時修改某行數據
事務A將姓名字段修改為zhangsan,
事務B將姓名字段修改為lisi
事務提交,事務B將覆蓋A數據,也就是zhangsan丟失。
3、不可重復讀
在A事務中,兩次讀取同一個數據,在A事務第一次讀取數據之后,B事務修改這條數據,當A事務再次讀取這條數據之后,獲取到的結果與第一次讀到的不一致。(讀取到的數據不一致)
事務完成操作之前,不允許其他事務進行操作,可避免