javascript
Spring事务 作者:哇塞大嘴好帅(我爱大嘴网)
Spring事務 作者:哇塞大嘴好帥(我愛大嘴網)
我愛大嘴好帥(我愛大嘴網) 我愛大嘴好帥(我愛大嘴網)1.事務的特性(ACID)
? 1.原子性(Atomicity)
? 2.一致性(Consistency)
? 3.隔離性(isolation)
? 4.持久性(Durability)
?
1.原子性(Atomicity)
? 比如張三給李四5塊錢,然后李四給趙四3塊錢。原子性就是這些步驟要不都執行要不都別執行,如果某一步出現問題就回滾撤銷。
2.一致性(Consistency)
? 數據保證在業務上是正確的
3.隔離性(isolation)
? 兩個事務的執行要互不影響,互不干擾,
4.持久性(Durability)
? 一旦提交事務成功,數據會到數據庫持久化保存,也就是擁有保存。
Spring事務管理機制
Spring事務時在數據庫事務的基礎上進行封裝擴展的,主要特性如下
? 1.支持原有的數據庫事務的隔離級別,加入了事務傳播的概念
? 2.提供國歌事務的合并或隔離的功能
? 3.提供聲明式事務,讓業務代碼與事務分離,事務變得更加易用(AOP)
Spring提供了事務相關的接口
Spring事務管理高層抽象主要包含3個接口,Spring的事務主要通過他們三個共同完成
? TransactionDefinition
? 事務定義: 事務定義信息(隔離、傳播、只讀、超時)
? PlatformTransactionManager
? 事務管理器,主要用于平臺相關事務的管理、
? TransactionStatus
? 獲取事務的運行狀態
1.1PlatformTransactionManager 事務管理器介紹
參考文檔:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/PlatformTransactionManager.html
commit方法提交事務
getTransaction獲取事務狀態 里面的TransactionDefinition是事務的定義 ,通過事務的定義信息去獲取狀態
rollback回滾
Spring為不同的持久層框架提供了不同的PlaformTransactionManaeg的接口實現
| org.springframework.jdbc.datasource.DataSourceTransactionManager | 使用Spring JDBC或iBatis進行持久化數據時使用 |
| org.springframework.orm.hibernate5.HibernateTransactionManager | 使用Hibernate5.0半斤星星持久化數據時使用 |
| org.springframework.orm.jpa.JpaTransactionManager | 使用JPA進行持久化時使用 |
| org.springframework.jdo.JdoTransactionManager | 當持久化機制是Jdo時使用 |
| org.springframework.trasanction.jta.JtaTransactionManager | 使用一個JTA實現來管理事務,在一個事務跨越多個資源必須使用. |
DatasourceTransactionManager針對JdbcTemplate、Mybatis事務控制,使用Connection(連接)進行事務管理
開啟事務connection.setAutoCommit(false),只有這個為false時候才能進行提交事務connection.commit() 、回滾事務connection.rollback();
1.2 TransactionDefinition 事務定義信息
參考文檔:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/TransactionDefinition.html
**getIsolationLevel ** 獲取隔離級別
getName 獲取當前事務的昵稱
getPropagationBehavior 獲取事務傳播行為
getTimeout 獲取超時時間,默認值是-1.-1就是不超時
isReadOnly 判斷事務是否只讀
常用的事務隔離級別
| DEFAULT | 使用后端數據庫默認的隔離別(Spring中的選擇項) |
| READ_UNCOMMITED | 允許你讀取還未提交的未改變的數據。可能導致臟讀、幻讀、不可重復讀 |
| READ_COMMITTED | 允許在并發事務已經提交后讀取。可防止臟讀,但幻讀和不重復讀依然可以發生 |
| REPEATABLE_READ | 對相同子彈的多次讀取是一致的,除非數據被事務本身改變。可防止臟、不可重復讀,但幻讀依然可能發生. |
| SERIALIZABLE | 100%服從ACID的隔離級別,確保不發生臟讀、幻讀、不可重復讀。這在所有的隔離級別中是最慢的,他是典型的通過完全鎖定在事務張設計的數據表來完成的。 |
DEFAULT是基于你選擇的數據庫,來選擇你數據庫的默認隔離級別
如:Mysql默認隔離級別為REPEATABLE_READ
? Oracle默認隔離級別 READ_COMMITTED
propagation behavior事務傳播行為
7種事務傳播級別
| PROPAGATION_REQUIRED | 支持當前事務,如果不存在就創建一個 |
| PROPAGATION_SUPPORTS | 支持當前事務,如果不存在,就不使用事務 |
| PROPAGATION_MANDATORY | 支持當前事務,如果不存在,拋出異常 |
| PROPAGATION_REQUIRES_NEW | 如果有事務存在,掛起當前事務,創建一個新的事務 |
| PROPAGATION_NOT_SUPPORTED | 以非事務方式運行,如果有事務存在,掛起當前事務 |
| PROPAGATION_NEVER | 以非事務方法運行,如果有事務存在,拋出異常 |
| PROPAGATION_NESTED | 如果當前事務存在,則嵌套事務執行,只針對DataSourceTransactionManager |
主要分為三大類:
PROPAGATION_REQUIRED(default) ,PROPAGATION_SUPPORTS ,PROPAGATION_MANDATORY
? 支持當前事務,A調用B,如果A事務還存在,那么A and B就處于同一個事務,事務默認的傳播級別為REQUIRED
PROPAGATION_REQUIRES_NEW,PROPAGATION_NOT_SUPPORTED,PROPAGATION_NEVER
? 不會支持原來的事務,如A調用B,如果A事務存在,B肯定不會和A處于一個事務。
常用的事務傳播行為:REQUIRES_NEW
PROPAGATION_NESTED 不常用
? 嵌套事務,只對DatasourcetransactionManager有效,底層使用JDBC的SavePoint機制,允許在同一個事務設置保存點,回滾保存點
常用的事務傳播行為:NESTED
REQUIRED NESTED REQUIRES_NEW的區分
? required 只有一個事務(默認,推薦)
? requires_new 存在兩個事務,如果事務存在,掛起事務,重新又開啟一個新的事務
? nested 嵌套事務,事務可以設置保存點,回滾到保存點,選擇提交or回滾
2.Spring事務管理
2.1編程式事務
? 編程式事務就是通過純代碼控制事務,手動提交手動回滾
2.1.1 xml配置
<!--事務管理器--> <bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property> </bean><!--事務管理的模板--> <bean id="transactionTemplate" class="org.springframework.transaction,support.TransactionTemplate"><property name="transactionManager" ref="transactionManager"></property> </bean>2.1.2 注解配置
@ComponentScan("com.dazuizui") public class TransactionConfig{/*** 事務管理器*/@Beanpublic TransactionTemple transactionTemplate(DataSourceTransactionManager dataSourceTransactionManager){TransactionTemplate transactionTemplate = new TransactionTemplate();transactionTemplate.setTransactionManager(transactionTemplate);return transactionTemplate;}@Beanpublic DataSourceTransactionManager transactionManager(DataSource dataSource){DataSourceTransactionManager dm = new DataSourceTransactionManager();dm.setDataSource(dataSource);return dm;}@Beanpublic JdbcTemplate jdbcTemplate(DataSource dataSource){JdbcTemplate jdbcTemplate = new JdbcTemplate();jdbcTemplate.setDtaSource(dataSource);return jdbcTemplate;}@Beanpublic DtaSource dataSource(){BasicDataSource ds = new BasicDataSource();ds.seturl("url");ds.setDriverClassName("com.mysql.jdbc.Driver")ds.setUsername("username");ds.setPassowrd("password");return ds;} }2.1.3 實現
/*** 通過xml配置使用*/ @Test public void test1(){ApplicationContext ca = new CLassPathXmlApplicationContext("applicationContext.xml");UserSerivce userBean = ca.getBean(UserSerivce.class);bean.test1();//執行數據庫操作 }/*** 執行注解配置文件模式*/ public void test2(){AnnotationConfigApplicationContext ac= new AnnotationConfigApplicationContext(TransactionConfig.class);UserSerivce userBean = ca.getBean(UserSerivce.class);bean.test1();//執行數據庫操作 }將調用數據庫事務通過Lambda表達式寫在transactiontemplate.execute()方法內進行事務事務管理
@Autowired private TransactionTemplate transactiontemplate //事務管理器public void test1(){transactiontemplate.execute(status - > {userMapper.zhuanqian(); //調用數據庫小張轉錢給小明int x = 10086;if(x==10086)throw new RuntimeException("error");userDao.income(); //小明收入小張轉的錢return null;}); }2.2 申明式事務
2.2.1基于AspectJ xml的配置方式
? 使用該申明式定要刪除配置文件中的事務管理模板中的配置。
? 也就是這個
<!--事務管理器--> <bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property> </bean>添加一個事務定義的配置和AOP的配置
<!--事務管理器--> <bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property> </bean><tx:advice id="txAdvice" transaction-manager="transactionManager"><!--增強事務的屬性配置--><td:attributes><!--isolation: default,事務隔離級別propagation: 事務傳播行為read-onlu: fase,是否只讀timeout: -1, 超時-1為默認值no-rollback-for: 發生那些異常不回滾rollback-for: 發生哪些異常滾事務--><tx:method name="方法名" isolation="DEFAULT" propagation="REQUIRED"> <!--save開頭的方法全部增強--><tx:method name="save*" isolation="DEFAULT" propagation="REQUIRED"></tx:method></td:attributes> </tx:advice><!--aop配置定義切面和切點信息--> <aop:config><!--定義切點:那些類的方法應用加強--><aop:pointct expression="excution(* com.dazuizui.beans.service..*.*(..))"id="mypointct"/><!--定義切面--><aop:advisor advice-ref="txAdvice" pointcut-ref="mypointcut"></aop:advisor> </aop:config>? 說一下Spring事務的配置:
? 第一種方法基于XML的配置方法,需要配置事務管理器,然后在配置事務的增強
? 事務定義主要配置,事務隔離級別、事務傳播行為、是否只讀、超時時間、發生那些異常不回滾、發生哪些異常滾事務
? 再通過aop:config設置切面和切入點
2.2.2 注解方法聲明式事務
@ComponentScan("com.dazuizui") @EnableTransactionManagement //開啟注解事務 public class TransactionConfig{ @Beanpublic DataSourceTransactionManager transactionManager(DataSource dataSource){DataSourceTransactionManager dm = new DataSourceTransactionManager();dm.setDataSource(dataSource);return dm;}@Beanpublic JdbcTemplate jdbcTemplate(DataSource dataSource){JdbcTemplate jdbcTemplate = new JdbcTemplate();jdbcTemplate.setDtaSource(dataSource);return jdbcTemplate;}@Beanpublic DtaSource dataSource(){BasicDataSource ds = new BasicDataSource();ds.seturl("url");ds.setDriverClassName("com.mysql.jdbc.Driver")ds.setUsername("username");ds.setPassowrd("password");return ds;} }如果你想使用事務那么就在Service類的上面加入**@Transactional**就是當前類下所有方法都進行事務管理,如果在方法上使用,那么就這個方法受到事務管理。
? 說一下Spring事務的配置:
? 基于注解的,在類上或者方法上添加**@Transactional**
3.Spring 傳播特性
3.1 什么是傳播特性? What is propagation charecteristics?
? 當一個事務方法被另一個事務方法調用時(方法A調用方法B),這個事務方法應該如何進行。
? for example:
@Service public class test1{@Transactionalpublic void function1(){System.out.println("funcion 1 method");function2();}@Transactionalpublic void function2(){System.out.println("function 2 medhod");} }3.2 Spring的7中傳播特性 7 kinds of propagation chanrecteristics of Spring
| PROPAGATION_REQUIRED | 默認事務類型,如果沒有就新建一個事務;如果有就加入當前事務。 |
| PROPAGATION_SUPPORTS | 如果沒有事務就非事物執行,如果有事務就使用當前事務 |
| PROPAGATION_MANDATORY | 如果沒有事務就拋出異常,如果有就使用當前事務 |
| PROPAGATION_REQUIRES_NEW | 如果沒有事務就非事務執行,所有有就將事務掛起 |
| PROPAGATION_NOT_SUPPORTED | 以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。 |
| PROPAGATION_NEVER | 如果有事務就拋出異常,如果沒有就非事務執行 |
| PROPAGATION_NESTED | 如果沒有事務就創建一個事務;如果有就在當前事務種嵌套其他事務 |
3.2.1詳細解說7種傳播特性
? 使用注解設置傳播特性例如
? @Transaction(propagation=Propagation.SUPPORTS)
? @Transaction(propagation=Propagation.NEVER)
3.2.1.1 PROPAGATION_NEVER
? 如果function1 或者 function2存在事務那么直接拋出異常
? for example
@Service public class test1{@Transactionalpublic void function1(){System.out.println("funcion 1 method");function2();}@Transactionalpublic void function2(){System.out.println("function 2 medhod");} }這樣會報錯
@Service public class test1{public void function1(){System.out.println("funcion 1 method");function2();}public void function2(){System.out.println("function 2 medhod");} }這樣就不會報錯
3.2.1.2 PROPAGATION_NOT_SUPPORTED
? 如果被調用方法發現調用它的方法存在事務那么就將事務掛起(我把你放一邊,我做我的事情),
for example
@Service public class test1{@Transactionalpublic void function1(){System.out.println("funcion 1 method");function2();}public void function2(){System.out.println("function 2 medhod");} }可以說PROPAGATION_NOT_SUPPORTED and PROPAGATION_NEVER 是死都不要事務
3.2.1.3 PROPAGATION_SUPPORTED
? 你有事務我就用事務執行,你沒有事務我就不按事務執行。
?
可以說propagation_not_supported是可有可無事務
3.2.1.4 propagation_requires_new
? 不管有沒有事務都必須創建一個事務,如果有事務,就將原來的事務掛起。我創建一個新的
? for example
@Service public class test1{@Transactionalpublic void function1(){System.out.println("funcion 1 method");function2();}@Transactionalpublic void function2(){System.out.println("function 2 medhod");} }? function2不管function1是否存在事務,我function2都必須創建一個事務,當我的事務走完了再去走function1的事務
? 可以實現子影響父,但父不影響子的效果
3.2.1.5 propagation_nested
? for example
@Service public class test1{@Transactionalpublic void function1(){System.out.println("funcion 1 method");function2();}@Transactionalpublic void function2(){System.out.println("function 2 medhod");} }如果function2出現了異常那么function1也跟著回滾
3.2.1.6 propagation_required (默認)
? 如果沒有事務我就創建一個事務,如果有事務那么我就用你的事務
3.2.1.7 propagation_mandatory
? 如果沒有事務我就報錯,如果有事務我就用你的
propagation_mandatory 和 propagation_required 和propagation_nested 和 propagation_requires_new 必須有一個事務
總結
以上是生活随笔為你收集整理的Spring事务 作者:哇塞大嘴好帅(我爱大嘴网)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 20170908一些随笔感悟
- 下一篇: DHCP的原理与配置