spring04-transaction

spring 的事務xml配置(事務使用xml配置, 其餘的ioc bean使用註解)


  1. 配置事務管理器git

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 引用數據源bean -->
        <property name="dataSource" ref="dataSource"/>
    </bean>
  2. 配置事務的通知github

    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*" propagation="REQUIRED" read-only="false"/>
            <tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
        </tx:attributes>
    </tx:advice>
    • 使用tx:advice標籤配置事務通知
      1. 屬性:
        • id:事務的惟一標識
        • transaction-manager:給事務通知提供一個事務管理器引用
  3. 配置AOP中的通用切入點表達式
    <aop:pointcut id="txPc" expression="execution(* cn.ann.service..*.*(..))"/>
  4. 創建事務通知和切入點表達式的對應關係
    <aop:advisor advice-ref="txAdvice" pointcut-ref="txPc"/>
  5. 配置事務的屬性
    • 使用tx:advice標籤內部的tx:attributes標籤配置事務屬性spring

      <tx:attributes>
          <tx:method name="*" propagation="REQUIRED" read-only="false"/>
          <tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
          <tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
      </tx:attributes>
      1. name: 要爲何方法配置事務. * 是通配符
      2. isolation:用於指定事務的隔離級別。默認值是DEFAULT,表示使用數據庫的默認隔離級別。
      3. propagation:用於指定事務的傳播行爲。默認值是REQUIRED,表示必定會有事務,增刪改的選擇。查詢方法能夠選擇SUPPORTS
      4. read-only:用於指定事務是否只讀。只有查詢方法才能設置爲true。默認值是false,表示讀寫
      5. timeout:用於指定事務的超時時間,默認值是-1,表示永不超時。若是指定了數值,以秒爲單位
      6. rollback-for:用於指定一個異常,當產生該異常時,事務回滾,產生其餘異常時,事務不回滾。沒有默認值。表示任何異常都回滾
      7. no-rollback-for:用於指定一個異常,當產生該異常時,事務不回滾,產生其餘異常時事務回滾。沒有默認值。表示任何異常都回滾


spring 事務的純註解配置


  1. 建立須要的bean(數據源, 事務管理器等)
  2. 在配置類使用註解開啓事務管理: @EnableTransactionManagement
  3. 配置通用切入點表達式:數據庫

    @Pointcut("execution(* cn.ann.service..*.*(..))")
    public void txPc(){}
  4. 爲每個須要配置事務的方法配置事務的屬性express

    @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
    public void transfer(String source, String target, Double money) {
        ...
    }
    
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public Account getAccountByName(String name) throws SQLException {
        ...
    }
    
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public Account getAccountById(Integer id) throws SQLException {
        ...
    }


spring 的編程式事務控制


  1. 建立事務管理器bean編程

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
  2. 建立事務模板beanide

    <bean id="txTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="transactionManager"/>
    </bean>
  3. 編寫業務代碼code

    @Service("accountService")
    public class AccountServiceImpl implements AccountService {
        @Resource(name = "txTemplate")
        private TransactionTemplate txTemplate;
        @Resource(name = "accountDao")
        private AccountDao dao;
    
        @Override
        public void transfer(String source, String target, Double money) {
            txTemplate.execute(status -> {
                try {
                    Account sourceAccount = dao.getAccountByName(source);
                    Account targetAccount = dao.getAccountByName(target);
                    sourceAccount.setAccountMoney(sourceAccount.getAccountMoney() - money);
                    dao.updateAccount(sourceAccount);
    //                int i = 1 / 0;
                    targetAccount.setAccountMoney(targetAccount.getAccountMoney() + money);
                    dao.updateAccount(targetAccount);
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                return null;
            });
        }
    
        @Override
        public Account getAccountById(Integer id) throws SQLException {
            return txTemplate.execute(status -> {
                try {
                    return dao.getAccountById(id);
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            });
        }
    
        @Override
        public Account getAccountByName(String name) throws SQLException {
            return txTemplate.execute(status -> {
                try {
                    return dao.getAccountByName(name);
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            });
        }
    }
  • 在代碼中能夠看到大量重複的部分: txTemplate.execute. 代碼用了lambda表達式, 因此感受並無那麼"震撼", 由於這個緣由, 開發中基本不用編程式事務控制

在開發中, 關於用註解仍是配置文件: 在公司沒有硬性要求的狀況下, 怎麼方便怎麼來. 我通常用配置文件配置事務
本片代碼: 此處 的全部spring04xml

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息