spring_事物

spring_事物mysql

 

1.事務spring

  1.1 什麼是事務:  sql

  • 事務(TRANSACTION) 是做爲單個邏輯工做單元執行的一系列操做。
  • 多個操做做爲一個總體向系統提交,要麼都執行,要麼都不執行。
  • 事務是一個不可分割的邏輯單元。

  1.2 事務的特性:數據庫

    事務具有如下四個特性,簡稱ACID屬性。express

  • 原子性(Atomicity):
    •   事務是一個完整的操做,事務的各步操做都是不可再分的,要麼都執行,要麼都不執行。
  • 一致性(Consistency):
    •   當事務完成時,數據必須處於一致的狀態。
  • 隔離性(Isolation):
    •   併發事務之間相互獨立、隔離,它不該以任何方式依賴於或影響其餘事務。
  • 持久性(Durability): 
    •   事務完成後,它對數據庫的修改被永久保持。

  1.3 mysql 事務操做---簡單api

ABCD 一個事務
Connection conn = null;
try{
  //1 得到鏈接
  conn = ...;
  //2 開啓事務
  conn.setAutoCommit(false);
  A
  B
  C
  D
  //3 提交事務
  conn.commit();
} catche(){
  //4 回滾事務
  conn.rollback();
}

  1.4 mysql 事務操做---Savepoint併發

需求:AB(必須),CD(可選) 
Connection conn = null;
Savepoint savepoint = null;  //保存點,記錄操做的當前位置,以後能夠回滾到指定的位置。(能夠回滾一部分)
try{
  //1 得到鏈接
  conn = ...;
  //2 開啓事務
  conn.setAutoCommit(false);
  A
  B
  savepoint = conn.setSavepoint();
  C
  D
  //3 提交事務
  conn.commit();
} catche(){
  if(savepoint != null){   //CD異常
     // 回滾到CD以前
     conn.rollback(savepoint);
     // 提交AB
     conn.commit();
  } else{   //AB異常
     // 回滾AB
     conn.rollback();
  }
}

2.事務管理介紹ide

  2.1三個頂級接口post

    PlatformTransactionManager  :平臺事務管理器ui

      spring要管理事務,必須使用事務管理器 進行事務配置時,必須配置事務管理器

    TransactionDefinition事務詳情(事務定義、事務屬性)

      spring用於肯定事務具體詳情,例如:隔離級別、是否只讀、超時時間等進行事務配置時,必須配置詳情。spring將配置項封裝到該對象實例。

    TransactionStatus事務狀態

      spring用於記錄當前事務運行狀態。例如:是否有保存點,事務是否完成。spring底層根據狀態進行相應操做。

  2.2 PlatformTransactionManager  事務管理器

    2.2.1 常見的事務管理器

            DataSourceTransactionManager      jdbc開發時事務管理器,採用JdbcTemplate

            HibernateTransactionManager      hibernate開發時事務管理器,整合hibernate

    2.2.2 api詳解   

      TransactionStatus getTransaction(TransactionDefinition definition) ,事務管理器 經過「事務詳情」,得到「事務狀態」,從而管理事務。

      void commit(TransactionStatus status)  根據狀態提交

      void rollback(TransactionStatus status) 根據狀態回滾

  2.3  TransactionStatus   事務狀態

    

  2.4 TransactionDefinition 事務詳情

 

    

 

    2.4.1 隔離問題:

      髒讀:一個事務讀到另外一個事務沒有提交的數據

           不可重複讀:一個事務讀到另外一個事務已提交的數據(update)

            虛讀(幻讀):一個事務讀到另外一個事務已提交的數據(insert)

     2.4.2 隔離級別:

      read uncommitted:讀未提交。存在3個問題

              read committed:讀已提交。解決髒讀,存在2個問題

              repeatable read:可重複讀。解決:髒讀、不可重複讀,存在1個問題。

              serializable :串行化。都解決,單事務。

         

 

     2.4.3 傳播行爲

      什麼是事務的傳播行爲:   事務傳播行爲用來描述由某一個事務傳播行爲修飾的方法被嵌套進另外一個方法的時事務如何傳播

 

        

        PROPAGATION_REQUIRED , required , 必須  【默認值】

                支持當前事務,A若是有事務,B將使用該事務。

                若是A沒有事務,B將建立一個新的事務。

        PROPAGATION_SUPPORTS ,supports ,支持

                支持當前事務,A若是有事務,B將使用該事務。

                若是A沒有事務,B將以非事務執行。

        PROPAGATION_MANDATORY,mandatory ,強制

                支持當前事務,A若是有事務,B將使用該事務。

                若是A沒有事務,B將拋異常。

        PROPAGATION_REQUIRES_NEW , requires_new ,必須新的

                若是A有事務,將A的事務掛起,B建立一個新的事務

                若是A沒有事務,B建立一個新的事務

        PROPAGATION_NOT_SUPPORTED ,not_supported ,不支持

                若是A有事務,將A的事務掛起,B將以非事務執行

                若是A沒有事務,B將以非事務執行

        PROPAGATION_NEVER ,never,從不

                若是A有事務,B將拋異常

                若是A沒有事務,B將以非事務執行

        PROPAGATION_NESTED ,nested ,嵌套

                A和B底層採用保存點機制,造成嵌套事務。

      掌握:PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、PROPAGATION_NESTED

 3.案例實現事務管理

  3.1搭建環境

    3.1.1數據庫:

    

    3.1.2 Dao層接口及其實現類

 

@Repository
public class UserDaoImpl implements UserDao{

    @Resource//運用註解方式注入JdbcTemplate
    private JdbcTemplate jdbcTemplate;

    @Override
    public int addMoney(double money,Integer id) {
        int update = jdbcTemplate.update("update  user set money=money+? where id=?", money, id);
        return update;
    }

    @Override
    public int removeMoney(double money,Integer id) {
        int update = jdbcTemplate.update("update  user set money=money-? where id=?", money, id);
        return update;
    }
}

    3.1.3 service層接口及其實現類

@Service("userService")
public class UserServiceImpl implements UserService {

    @Resource
    private UserDao userDao;
    

    @Override
    public void tranMoney(double money) {
        userDao.addMoney(money,1);
        //只能對運行時異常進行回滾
        int i=1/0;
        userDao.removeMoney(money,2);

    }
}

    3.1.4 大配置文件數據源配置及事務管理器

<!--導入jdbc配置文件-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
   <!-- 數據源配置-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    <!--包掃描儀-->
    <context:component-scan base-package="cn.spring.transaction"></context:component-scan>

    <!--設置JdbcTemplate模板-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--事務管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>    </bean>
 

  3.2採用代理工廠實現事務管理

<!--方式一:事務代理工廠-->
    <bean id="factoryBean" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <!--設置事務管理器-->
        <property name="transactionManager" ref="transactionManager"></property>
        <!--設置目標對象-->
        <property name="target" ref="userService" ></property>
        <!--事務的隔離級別和傳播行爲-->
        <property name="transactionAttributes">
            <props><!--鍵值 key爲具體的方法名 value能夠爲傳播行爲或隔離級別-->
                <prop key="tranMoney">ISOLATION_READ_COMMITTED</prop>
            </props>
        </property>
    </bean>
 

  3.3 Aop配置實現事務管理

<!--方式二:AOP實現事務-->
    <!--通知-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!-- transferMoney的事務隔離級別和傳播行爲 -->
            <tx:method name="tranMoney" propagation="REQUIRED" isolation="READ_COMMITTED"/>
        </tx:attributes>
    </tx:advice>
    
    <!--切面-->
    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(* *..transaction.service.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"></aop:advisor>
    </aop:config>
 

  3.4基於註解實現事務管理

    配置文件:

<!--使用註解實現事務-->
    <!--開啓事務的註解配置-->
    <tx:annotation-driven/>

    業務層註解:

 
@Service("userService")
public class UserServiceImpl implements UserService {

    @Resource
    private UserDao userDao;

    @Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
    @Override
    public void tranMoney(double money) {
        userDao.addMoney(money,1);
        //只能對運行時異常進行回滾
        int i=1/0;
        userDao.removeMoney(money,2);

    }
}
相關文章
相關標籤/搜索