原文鏈接http://zhhll.icu/2021/01/06/%E6%A1%86%E6%9E%B6/spring/Spring%E4%BA%8B%E5%8A%A1/
spring事務
事務介紹
一個事務要么同時成功,要么同時失敗
特性
-
Atomic原子性 事務是由一個或多個活動組成的一個作業單元,原子性確保事務中的所有操作全部發生或全部不發生
-
Consistent一致性 一旦事務完成,系統必須確保它所建模的業務處于一致的狀態
-
Isolated隔離性 事務允許多個用戶對資料進行操作,每個用戶的操作不會與其他用戶糾纏在一起
-
Durable持久性 一旦事務完成,事務的結果應該持久化
事務隔離級別
- DEFAULT 使用底層資料庫預設的隔離層級
- READ_UNCOMMITTED (讀未提交的資料) 允許事務讀取其他并行的事務還沒提交的資料,臟讀、不可重復讀、幻讀問題都存在
- READ_COMMITTED(讀已提交的資料) 只允許事務讀取其他并行事務提交的資料,可以避免臟讀,但是不可重復讀和幻讀仍存在
- REPEATABLE_READ(可重復讀) 確保事務可以多次從一個欄位中讀取相同的值,在這個事務持續期間,禁止其他事務對這個欄位進行更新,可以避免臟讀和不可重復讀,但幻讀仍存在(Mysql默認的事務隔離級別)
- SERIALIZABLE(串行化) 確保事務可以從一個表中讀取相同的行,在這個事務持續期間,禁止其他事務對該表執行插入、更新和洗掉操作,所有并發問題都可以避免,但是性能低下
傳播行為
-
PROPAGATION_REQUIRED 支持當前事務,如果當前沒有事務,就新建一個事務
-
PROPAGATION_SUPPORTS 支持當前事務,如果當前沒有事務,就以非事務方式執行
-
PROPAGATION_MANDATORY 支持當前事務,如果當前沒有事務,就拋出例外
-
PROPAGATION_REQUIRED_NEW 新建事務,如果當前存在事務,把當前事務掛起
-
PROPAGATION_NOT_SUPPORTED 以非事務方式執行操作,如果當前存在事務,就把當前事務掛起
-
PROPAGATION_NEVER 以非事務方式執行操作,如果當前存在事務,則拋出例外
-
PROPAGATION_NESTED 如果當前存在事務,則在嵌套事務內執行,如果當前沒有事務,則新建事務
只讀
事務只進行讀取操作
readOnly=true 告訴spring當前事務只會進行讀取操作,不會進行修改操作,可以幫助資料庫引擎優化
注:如果設定為只讀的話,千萬不要在事務里修改資料,使用只讀操作時,spring不會進行加鎖處理,如果修改資料的話,會出現問題
事務超時
事務時間過長,則回滾
回滾規則
rollback-for 指事務對于那些檢查型例外應當回滾而不提交(默認spring會對所有的運行時例外回滾)
no-rollback-for 指事務對于那些例外繼續執行不回滾
事務的使用
create table user(
id int primary key AUTO_INCREMENT,
name varchar(20) not null,
account double
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into user (name,account) values('張三',1000);
insert into user (name,account) values('李四',1000);
<!-- 事務 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.29.RELEASE</version>
</dependency>
<!-- 事務管理器以及資料源 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.29.RELEASE</version>
</dependency>
<!-- mysql驅動 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
使用注解
在這里采用的是spring中的資料源
<!-- 資料源 -->
<bean id="dataSource" >
<property name="driverClassName" value="https://www.cnblogs.com/life-time/p/com.mysql.jdbc.Driver" />
<property name="url" value="https://www.cnblogs.com/life-time/p/jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=utf-8" />
<property name="username" value="https://www.cnblogs.com/life-time/p/root" />
<property name="password" value="https://www.cnblogs.com/life-time/p/123456" />
</bean>
<!-- 事務管理器 -->
<bean id="transactionManager" >
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 啟用事務注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
當然由于是使用的注解,不要忘記組件掃描
<context:component-scan base-package="com.zhanghe.study.spring4.beans.tx"/>
之后就可以在要保證事務的方法上配置@Transactional以及在該注解上配置相應的事務隔離級別(isolation)、事務傳播行為(propagation)、對哪些例外執行回滾(rollbackFor)以及不執行回滾(noRollbackFor) 默認對運行時例外回滾
使用XML
<!-- 資料源 -->
<bean id="dataSource" >
<property name="driverClassName" value="https://www.cnblogs.com/life-time/p/com.mysql.jdbc.Driver" />
<property name="url" value="https://www.cnblogs.com/life-time/p/jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=utf-8" />
<property name="username" value="https://www.cnblogs.com/life-time/p/root" />
<property name="password" value="https://www.cnblogs.com/life-time/p/123456" />
</bean>
<!-- 事務管理器 -->
<bean id="transactionManager" >
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 使用xml配置事務屬性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 根據方法名指定特定的事務屬性 -->
<tx:method name="get*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="save*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 使用事務切入點,把事務切入點和事務屬性關聯起來 -->
<aop:config>
<aop:pointcut id="pointCut" expression="execution(* com.zhanghe.study.spring4.beans.tx.UserService.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/>
</aop:config>
由于本身的博客百度沒有收錄,博客地址http://zhhll.icu
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/264371.html
標籤:Java
