<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      Fork me on GitHub

      Spring5.0源碼學(xué)習(xí)系列之事務(wù)管理概述

      Spring源碼學(xué)習(xí)系列博客專欄:鏈接

      Spring5.0源碼學(xué)習(xí)系列之事務(wù)管理概述(十一),在學(xué)習(xí)事務(wù)管理的源碼之前,需要對事務(wù)的基本理論比較熟悉,所以本章節(jié)會對事務(wù)管理的基本理論進行描述

      1、什么是事務(wù)?

      事務(wù)就是一組原子性的SQL操作,或者說一個獨立的工作單元。在計算機術(shù)語中是指訪問并可能更新數(shù)據(jù)庫中各種數(shù)據(jù)項的一個程序執(zhí)行單元(unit)

      注意:Spring的事務(wù)支持是基于數(shù)據(jù)庫事務(wù)的,在MySQL數(shù)據(jù)庫中目前只有InnoDB或者NDB集群引擎才支持,MySQL5.0之前的默認MyISAM存儲引擎是不支持事務(wù)的

      2、事務(wù)的ACID特性

      ACID其實是事務(wù)特性的英文首字母縮寫,具體含義是:原子性(atomicity)、一致性(consistency)、隔離性(isolation)、持久性(durability)

      • 原子性(atomicity):事務(wù)是一個原子操作,由一系列動作組成。整個事務(wù)中的所有操作要么全部提交成功,要么全部失敗回滾;
      • 一致性(consistency):數(shù)據(jù)庫總是從一個一致性的狀態(tài)轉(zhuǎn)換到另外一個一致性的狀態(tài),執(zhí)行事務(wù)前后,數(shù)據(jù)保持一致;
      • 隔離性(isolation): 因為有多個事務(wù)處理同個數(shù)據(jù)的情況,因此每個事務(wù)都應(yīng)該與其他事務(wù)隔離開來,防止數(shù)據(jù)臟讀、不可重復(fù)讀等等情況;
      • 持久性(durability):一旦事務(wù)提交,則其所做的修改就會永久保存到數(shù)據(jù)庫中。此時即使系統(tǒng)崩潰,修改的數(shù)據(jù)也不會丟;

      3、什么是臟讀、不可重復(fù)讀、幻讀?

      • 臟讀
        在A事務(wù)修改數(shù)據(jù),提交事務(wù)之前,另外一個B事務(wù)讀取了A事務(wù)未提交事務(wù)之前的數(shù)據(jù),這種情況稱之為臟讀(Dirty Read)
      • 不可重復(fù)讀
        一個A事務(wù)在讀取某些數(shù)據(jù),第1次讀取出來的數(shù)據(jù)結(jié)果和第2次讀取出來的不一致,因為在兩次數(shù)據(jù)讀取期間,另外的事務(wù)對數(shù)據(jù)進行了更改
      • 幻讀
        幻讀和不可重復(fù)讀是很類似的,不同的地方在于幻讀側(cè)重于事務(wù)對數(shù)據(jù)的刪除或者新增,都是因為在兩次數(shù)據(jù)讀取期間,因為另外事務(wù)對數(shù)據(jù)的刪除還是新增,導(dǎo)致第2次讀取的數(shù)據(jù)和第1次不一致

      4、Spring事務(wù)管理核心接口

      在這里插入圖片描述
      在這里插入圖片描述

      在這里插入圖片描述

      在這里插入圖片描述

      5、事務(wù)隔離級別

      定義:事務(wù)的隔離級別定義了一個事務(wù)可能受其他并發(fā)事務(wù)影響的程度。隔離級別可以不同程度的解決臟讀、不可重復(fù)讀、幻讀。

      隔離級別 描述 臟讀 不可重復(fù)讀 幻讀
      ISOLATION_DEFAULT 使用后端數(shù)據(jù)庫默認的隔離級別,默認的為Repeatable read (可重復(fù)讀)
      ISOLATION_READ_UNCOMMITTED 不可提交讀,允許讀取尚未提交事務(wù)的數(shù)據(jù),可能會導(dǎo)致臟讀、不可重復(fù)讀、幻讀
      ISOLATION_READ_COMMITTED 提交讀,讀取并發(fā)事務(wù)已經(jīng)提交的數(shù)據(jù),可以阻止臟讀,但是幻讀或不可重復(fù)讀仍有可能發(fā)生
      ISOLATION_REPEATABLE_READ 可重復(fù)讀,可以阻止臟讀和不可重復(fù)讀,但幻讀仍有可能發(fā)生
      ISOLATION_SERIALIZABLE 串行化,這種級別是最高級別,服從ACID的隔離級別,確保阻止臟讀、不可重復(fù)讀以及幻讀

      6、事務(wù)的傳播行為

      事務(wù)傳播行為 描述
      PROPAGATION_REQUIRED 必須,默認值。如果A有事務(wù),B將使用該事務(wù);如果A沒有事務(wù),B將創(chuàng)建一個新的事務(wù)
      PROPAGATION_SUPPORTS 支持。如果A有事務(wù),B將使用該事務(wù);如果A沒有事務(wù),B將以非事務(wù)執(zhí)行
      PROPAGATION_MANDATORY 強制。A如果有事務(wù),B將使用該事務(wù);如果A沒有事務(wù),B將拋異常
      PROPAGATION_REQUIRES_NEW 必須新的。如果A有事務(wù),將A的事務(wù)掛起,B創(chuàng)建一個新的事務(wù);如果A沒有事務(wù),B創(chuàng)建一個新的事務(wù)。
      PROPAGATION_NOT_SUPPORTED 不支持。如果A有事務(wù),將A的事務(wù)掛起,B將以非事務(wù)執(zhí)行;如果A沒有事務(wù),B將以非事務(wù)執(zhí)行。
      PROPAGATION_NEVER 從不。如果A有事務(wù),B將拋異常;如果A沒有事務(wù),B將以非事務(wù)執(zhí)行
      PROPAGATION_NESTED 嵌套。A和B底層采用保存點機制,形成嵌套事務(wù)。

      7、事務(wù)管理其它屬性

      前面介紹了事務(wù)管理的隔離級別和傳播行為這兩個重要的屬性,接著介紹一下事務(wù)的其它屬性

      • 事務(wù)超時屬性
        事務(wù)超時,屬性值是timeout,指一個事務(wù)所允許執(zhí)行的最長時間,如果超過該時間限制但事務(wù)還沒有完成,則自動回滾事務(wù)。以 int 的值來表示超時時間,其單位是秒,默認值為-1。
      • 事務(wù)只讀屬性
        屬性值readOnly,對于只有讀取數(shù)據(jù)查詢的事務(wù),可以指定事務(wù)類型為 readonly,即只讀事務(wù)。只讀事務(wù)不涉及數(shù)據(jù)的修改,數(shù)據(jù)庫會提供一些優(yōu)化手段,所以對于業(yè)務(wù)很明確的接口,可以適當加上只讀屬性
      • 事務(wù)回滾規(guī)則
        屬性值rollbackFor,默認情況下,事務(wù)只有遇到運行期異常(RuntimeException 的子類)時才會回滾,Error 也會導(dǎo)致事務(wù)回滾
      屬性名 說明
      propagation 事務(wù)的傳播行為,默認值為 REQUIRED
      isolation 事務(wù)的隔離級別,默認值采用 DEFAULT
      timeout 事務(wù)的超時時間,默認值-1,表示不會超時,如果設(shè)置其它值,超過該時間限制但事務(wù)還沒有完成,則自動回滾事務(wù)
      readOnly 指定事務(wù)為只讀事務(wù),默認值false
      rollbackFor 指定能夠觸發(fā)事務(wù)回滾的異常類型,并且可以指定多個異常類型。

      8、Spring事務(wù)實現(xiàn)方式

      Spring事務(wù)代碼實現(xiàn)方式有兩種,一種是編程式事務(wù),一種是聲明式事務(wù)。所謂編程式事務(wù),是指通過Spring框架提供的TransactionTemplate或者直接使用底層的PlatformTransactionManager。聲明式事務(wù),依賴Spring AOP,配置文件中做相關(guān)的事務(wù)規(guī)則聲明或者直接使用@Transactional注解

      下面給出一個典型的轉(zhuǎn)賬匯款例子,先不用事務(wù)的方式實現(xiàn),接著使用編程式事務(wù)和聲明式事務(wù)進行事務(wù)管理

      package com.example.springframework.dao.impl;
      
      import com.example.springframework.dao.AccountDao;
      import org.springframework.jdbc.core.support.JdbcDaoSupport;
      
      /**
       * <pre>
       *      AccountDaoImpl
       * </pre>
       *
       * <pre>
       * @author mazq
       * 修改記錄
       *    修改后版本:     修改人:  修改日期: 2021/03/25 15:51  修改內(nèi)容:
       * </pre>
       */
      public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
      
          @Override
          public void out(String outer, int money) {
              super.getJdbcTemplate().update("update account set money = money - ? where usercode=?",money,outer);
          }
      
          @Override
          public void in(String inner, int money) {
              super.getJdbcTemplate().update("update account set money = money + ? where usercode = ?",money , inner);
          }
      }
      
      
      package com.example.springframework.service.impl;
      
      import com.example.springframework.dao.AccountDao;
      import com.example.springframework.service.AccountService;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.jdbc.core.support.JdbcDaoSupport;
      import org.springframework.stereotype.Service;
      
      
      /**
       * <pre>
       *      AccountServiceImpl
       * </pre>
       *
       * <pre>
       * @author mazq
       * 修改記錄
       *    修改后版本:     修改人:  修改日期: 2021/03/25 15:55  修改內(nèi)容:
       * </pre>
       */
      @Service
      public class AccountServiceImpl extends JdbcDaoSupport implements AccountService {
      
          AccountDao accountDao;
      
          public void setAccountDao(AccountDao accountDao) {
              this.accountDao = accountDao;
          }
      
          public void transfer(final String outer,final String inner,final int money){
              accountDao.out(outer , money);
              // exception
              // int i = 1 / 0;
              accountDao.in(inner , money);
          }
          
      }
      

      代碼例子看起來是挺正常的,不過假如在accountDao.out(outer , money);accountDao.in(inner , money);兩個事務(wù)執(zhí)行期間,發(fā)生異常,這時會怎么樣?效果如圖:Jack的賬號已經(jīng)轉(zhuǎn)賬成功,轉(zhuǎn)了1000,不過Tom并沒有收到匯款,這種情況在實際生活中肯定是不允許的,所以需要使用事務(wù)進行管理
      在這里插入圖片描述

      9、Spring編程式事務(wù)

      Spring編程式事務(wù)實現(xiàn),通過Spring框架提供的TransactionTemplate或者直接使用底層的PlatformTransactionManager

      • 使用TransactionTemplate的方式
      private AccountDao accountDao;
      private TransactionTemplate transactionTemplate;
      
      public void setAccountDao(AccountDao accountDao) {
          this.accountDao = accountDao;
      }
      public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
          this.transactionTemplate = transactionTemplate;
      }
      
      @Override
      public void transfer(final String outer,final String inner,final int money){
          transactionTemplate.execute(new TransactionCallbackWithoutResult() {
              @Override
              protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                  accountDao.out(outer , money);
                  // exception
                  int i = 1 / 0;
                  accountDao.in(inner , money);
              }
          });
      }
      
      • 使用PlatformTransactionManager的方式
      private AccountDao accountDao;
      
      public void setAccountDao(AccountDao accountDao) {
          this.accountDao = accountDao;
      }
      
      @Override
      public void transferTrans(String outer, String inner, int money) {
          DataSourceTransactionManager dataSourceTransactionManager =
                  new DataSourceTransactionManager();
          // 設(shè)置數(shù)據(jù)源
          dataSourceTransactionManager.setDataSource(super.getJdbcTemplate().getDataSource());
          DefaultTransactionDefinition transDef = new DefaultTransactionDefinition();
          // 設(shè)置傳播行為屬性
          transDef.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRED);
          TransactionStatus status = dataSourceTransactionManager.getTransaction(transDef);
          try {
              accountDao.out(outer , money);
              // exception
              int i = 1 / 0;
              accountDao.in(inner , money);
              //commit
              dataSourceTransactionManager.commit(status);
          } catch (Exception e) {
              // rollback
              dataSourceTransactionManager.rollback(status);
          }
      }
      

      10、Spring聲明式事務(wù)

      Spring聲明式事務(wù)依賴于Spring AOP,通過配置文件中做相關(guān)的事務(wù)規(guī)則聲明或者直接使用@Transactional注解

      • AOP規(guī)則聲明方式
        這種方式在 applicationContext.xml 文件中配置 aop 自動生成代理,進行事務(wù)管理
      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
             xmlns:aop="http://www.springframework.org/schema/aop"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
      
          <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
              <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
              <property name="url" value="jdbc:mysql://127.0.0.1:3306/test"></property>
              <property name="username" value="root"></property>
              <property name="password" value="minstone"></property>
          </bean>
      
          <bean id="accountDao" class="com.example.springframework.dao.impl.AccountDaoImpl">
              <property name="dataSource" ref="dataSource"></property>
          </bean>
      
          <bean id="accountService" class="com.example.springframework.service.impl.AccountServiceImpl">
              <property name="accountDao" ref="accountDao"></property>
              <property name="dataSource" ref="dataSource"></property>
          </bean>
      	<!-- 事務(wù)管理器配置 -->
          <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
              <property name="dataSource" ref="dataSource"></property>
          </bean>
      
          <!-- xml配置事務(wù) propagation 傳播行為isolation 隔離級別-->
          <tx:advice id="txAdvice" transaction-manager="txManager">
              <tx:attributes>
                  <tx:method name="transfer" propagation="REQUIRED" isolation="DEFAULT"/>
              </tx:attributes>
          </tx:advice>
      	
      	<!-- 配置所有的Service方法都支持事務(wù)-->
          <aop:config>
           <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.example.springframework.service..*.*(..))"/>
       </aop:config>
      
        
      </beans>
      
      • 使用AOP注解方式
        在applicationContext.xml 配置事務(wù)管理器,將并事務(wù)管理器交予spring,在目標類或目標方法添加注解即可 @Transactional, proxy-target-class設(shè)置為 true : 底層強制使用cglib 代理

      注意點:@Transactional只能用于public方法,不管是加上類上還是方法上

      <!-- 事務(wù)管理器配置 -->
      <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
              <property name="dataSource" ref="dataSource"></property>
          </bean>
      
      <!-- 配置 Annotation 驅(qū)動,掃描@Transactional注解的類定義事務(wù)  -->
      <tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>
      

      通過上述管理之后,一旦發(fā)生異常,兩邊都會進行事務(wù)回滾,沒有異常,正常提交事務(wù)
      在這里插入圖片描述

      本文例子代碼可以在github找到下載鏈接

      posted @ 2021-05-27 22:20  smileNicky  閱讀(463)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲欧洲色图片网站| 亚洲成aⅴ人在线观看| 亚洲乱熟女一区二区三区| 67194亚洲无码| 免费无码高H视频在线观看| 亚洲欧美色综合影院| 一本精品中文字幕在线| 国产精品99久久久久久董美香 | 五月天国产成人av免费观看| 国产极品丝尤物在线观看| av新版天堂在线观看| 性色av无码不卡中文字幕| 精品国产人妻一区二区三区久久| 麻豆国产成人AV在线播放| 啊灬啊灬啊灬快灬高潮了电影片段| 中文字幕亚洲无线码一区女同| 久久久精品人妻一区二区三区 | 日韩中文字幕人妻一区| 久久综合给合久久狠狠狠88| 午夜福利精品国产二区| 国产久免费热视频在线观看| 亚洲欧美一区二区成人片| 亚洲人成电影在线天堂色| 91亚洲国产成人久久蜜臀| 18岁日韩内射颜射午夜久久成人| 蜜桃av亚洲精品一区二区 | 日韩深夜福利视频在线观看| 精品一区二区三区在线视频观看| 高安市| 亚洲中文字幕伊人久久无码 | 日产国产精品亚洲系列| 日韩精品一区二区三区久| 久久人人爽人人爽人人av| 雅江县| 久久精品蜜芽亚洲国产av| 国产愉拍91九色国产愉拍| 欧美18videosex性欧美tube1080 | 亚洲欧洲一区二区免费| yy111111少妇无码影院| 精品国产一区二区三区性色| 秋霞电影院午夜无码免费视频|