手寫Spring事務框架-基於aop 技術

概述

所謂編程式事務指的是通過編碼方式實現事務,即類似於JDBC編程實現事務管理。管理使用TransactionTemplate或者直接使用底層的PlatformTransactionManager。對於編程式事務管理,spring推薦使用TransactionTemplate。

案例

使用編程事務實現手動事務

使用編程事務實現,手動事務 begin、commit、rollback

 

@Component

public class TransactionUtils {

 

      @Autowired

      private DataSourceTransactionManager dataSourceTransactionManager;

 

      // 開啓事務

      public TransactionStatus begin() {

            TransactionStatus transaction = dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute());

            return transaction;

      }

 

      // 提交事務

      public void commit(TransactionStatus transactionStatus) {

            dataSourceTransactionManager.commit(transactionStatus);

      }

 

      // 回滾事務

      public void rollback(TransactionStatus transactionStatus) {

            dataSourceTransactionManager.rollback(transactionStatus);

      }

}

 

@Service

public class UserService {

     @Autowired

     private UserDao userDao;

     @Autowired

     private TransactionUtils transactionUtils;

 

     public void add() {

          TransactionStatus transactionStatus = null;

          try {

               transactionStatus = transactionUtils.begin();

               userDao.add("zhangsan", 27);

               int i = 1 / 0;

               System.out.println("我是add方法");

               userDao.add("lisi", 16);

               transactionUtils.commit(transactionStatus);

          } catch (Exception e) {

               e.printStackTrace();

          } finally {

               if (transactionStatus != null) {

                    transactionStatus.rollbackToSavepoint(transactionStatus);

               }

          }

 

     }

 

}

AOP技術封裝手動事務

@Component

@Aspect

public class AopTransaction {

      @Autowired

      private TransactionUtils transactionUtils;

 

      // // 異常通知

      @AfterThrowing("execution(* com.haha.service.UserService.add(..))")

      public void afterThrowing() {

            System.out.println("程序已經回滾");

            // 獲取程序當前事務 進行回滾

            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

      }

 

      // 環繞通知

      @Around("execution(* com.haha.service.UserService.add(..))")

      public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

            System.out.println("開啓事務");

            TransactionStatus begin = transactionUtils.begin();

            proceedingJoinPoint.proceed();

            transactionUtils.commit(begin);

            System.out.println("提交事務");

      }

 

}

 

使用事務注意事項

 

事務是程序運行如果沒有錯誤,會自動提交事物,如果程序運行發生異常,則會自動回滾。

如果使用了try捕獲異常時.一定要在catch裏面手動回滾。

事務手動回滾代碼

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

 

聲明事務實現

概述

管理建立在AOP之上的。其本質是對方法前後進行攔截,然後在目標方法開始之前創建或者加入一個事務,在執行完目標方法之後根據執行情況提交或者回滾事務。聲明式事務最大的優點就是不需要通過編程的方式管理事務,這樣就不需要在業務邏輯代碼中摻雜事務管理的代碼,只需在配置文件中做相關的事務規則聲明(或通過基於@Transactional註解的方式),便可以將事務規則應用到業務邏輯中。

       顯然聲明式事務管理要優於編程式事務管理,這正是spring倡導的非侵入式的開發方式。

 

聲明式事務管理使業務代碼不受污染,一個普通的POJO對象,只要加上註解就可以獲得完全的事務支持。和編程式事務相比,聲明式事務唯一不足地方是,後者的最細粒度只能作用到方法級別,無法做到像編程式事務那樣可以作用到代碼塊級別。但是即便有這樣的需求,也存在很多變通的方法,比如,可以將需要進行事務管理的代碼塊獨立爲方法等等。

XML實現聲明

 

註解版本聲明

<beans xmlns="http://www.springframework.org/schema/beans"

      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"

      xmlns:context="http://www.springframework.org/schema/context"

      xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"

      xsi:schemaLocation="http://www.springframework.org/schema/beans

       http://www.springframework.org/schema/beans/spring-beans.xsd

      http://www.springframework.org/schema/context

         http://www.springframework.org/schema/context/spring-context.xsd

         http://www.springframework.org/schema/aop

         http://www.springframework.org/schema/aop/spring-aop.xsd

         http://www.springframework.org/schema/tx

      http://www.springframework.org/schema/tx/spring-tx.xsd">

 

 

      <!-- 開啓註解 -->

      <context:component-scan base-package="com.haha"></context:component-scan>

      <!-- 1. 數據源對象: C3P0連接池 -->

      <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">

            <property name="driverClass" value="com.mysql.jdbc.Driver"></property>

            <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>

            <property name="user" value="root"></property>

            <property name="password" value="root"></property>

      </bean>

 

      <!-- 2. JdbcTemplate工具類實例 -->

      <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">

            <property name="dataSource" ref="dataSource"></property>

      </bean>

 

      <!-- 配置事物 -->

      <bean id="dataSourceTransactionManager"

            class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

            <property name="dataSource" ref="dataSource"></property>

      </bean>

      <!-- 開啓註解事物 -->

      <tx:annotation-driven transaction-manager="dataSourceTransactionManager" />

</beans>

 

用法

      @Transactional

      public void add() {

            userDao.add("wangmazi", 27);

            int i = 1 / 0;

            System.out.println("我是add方法");

            userDao.add("zhangsan", 16);

      }

發佈了365 篇原創文章 · 獲贊 23 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章