Spring的事務管理幾種配置方式(例子)

  事務原本是數據庫中的概念,在 Dao 層。但一般情況下,需要將事務提升到業務層,即 Service 層。這樣做是爲了能夠使用事務的特性來管理具體的業務。  

  在 Spring 中通常可以通過以下三種方式來實現對事務的管理: 
    (1)使用 Spring 的事務代理工廠管理事務 
    (2)使用 Spring 的事務註解管理事務 
    (3)使用 AspectJ 的 AOP 配置管理事務 

  Spring事務管理API:

    Spring 的事務管理,主要用到兩個事務相關的接口。

    (1)事務管理器接口 
        事務管理器是 PlatformTransactionManager 接口對象。其主要用於完成事務的提交、回滾,及獲取事務的狀態信息。查看 SpringAPI 幫助文檔:Spring 框架解壓目錄下的docs/javadoc-api/index.html。

Modifier and TypeMethod and Description
voidcommit(TransactionStatus status)
Commit the given transaction, with regard to its status.
TransactionStatusgetTransaction(TransactionDefinition definition)
Return a currently active transaction or create a new one, according to the specified propagation behavior.
voidrollback(TransactionStatus status)
Perform a rollback of the given transaction.

      A、常用的兩個實現類 
        PlatformTransactionManager 接口有兩個常用的實現類:  
          DataSourceTransactionManager:使用 JDBC 或 iBatis  進行持久化數據時使用。  
          HibernateTransactionManager:使用 Hibernate 進行持久化數據時使用。 
      B、Spring 的回滾方式 
        Spring 事務的默認回滾方式是:發生運行時異常時回滾,發生受查異常時提交。不過,對於受查異常,程序員也可以手工設置其回滾方式

    (2)事務定義接口:
      事務定義接口 TransactionDefinition 中定義了事務描述相關的三類常量:事務隔離級別事務傳播行爲事務默認超時時限,及對它們的操作

      A、定義了五個事務隔離級別常量: 
        這些常量均是以 ISOLATION_開頭。即形如 ISOLATION_XXX。 
          DEFAULT:採用DB默認的事務隔離級別。MySql的默認爲REPEATABLE_READ;  Oracle默認爲 READ_COMMITTED。 
          READ_UNCOMMITTED:讀未提交。未解決任何併發問題。 
          READ_COMMITTED:讀已提交。解決髒讀,存在不可重複讀與幻讀。  
          REPEATABLE_READ:可重複讀。解決髒讀、不可重複讀,存在幻讀  
          SERIALIZABLE:串行化。不存在併發問題。

      B、定義了七個事務傳播行爲常量 
        所謂事務傳播行爲是指,處於不同事務中的方法在相互調用時,執行期間事務的維護情況。如,A 事務中的方法 doSome()調用 B 事務中的方法 doOther(),在調用執行期間事務的維護情況,就稱爲事務傳播行爲。事務傳播行爲是加在方法上的。  
事務傳播行爲常量都是以 PROPAGATION_  開頭,形如 PROPAGATION_XXX。  
          REQUIRED:指定的方法必須在事務內執行。若當前存在事務,就加入到當前事務中;若當前沒有事務,則創建一個新事務。這種傳播行爲是最常見的選擇,也是Spring 默認的事務傳播行爲。  
          如該傳播行爲加在 doOther()方法上。若 doSome()方法在執行時就是在事務內的,則 doOther()方法的執行也加入到該事務內執行。若 doSome()方法沒有在事務內執行,則 doOther()方法會創建一個事務,並在其中執行。

          SUPPORTS:指定的方法支持當前事務,但若當前沒有事務,也可以以非事務方式執行。 

          MANDATORY:指定的方法必須在當前事務內執行,若當前沒有事務,則直接拋出異常。

          REQUIRES_NEW:總是新建一個事務,若當前存在事務,就將當前事務掛起,直到新事務執行完畢。

          NOT_SUPPORTED:指定的方法不能在事務環境中執行,若當前存在事務,就將當前事務掛起。

          NEVER:指定的方法不能在事務環境下執行,若當前存在事務,就直接拋出異常。

          NESTED:指定的方法必須在事務內執行。若當前存在事務,則在嵌套事務內執行;若當前沒有事務,則創建一個新事務。

      C、定義了默認事務超時時限 
        常量 TIMEOUT_DEFAULT 定義了事務底層默認的超時時限,及不支持事務超時時限設置的 none 值。 
        注意,事務的超時時限起作用的條件比較多,且超時的時間計算點較複雜。所以,該值一般就使用默認值即可。

 

  Spring事務代碼詳解:

    要求:實現模擬購買股票。存在兩個實體:銀行賬戶 Account 與股票賬戶 Stock。當要購買股票時,需要從 Account 中扣除相應金額的存款,然後在 Stock 中增加相應的股票數量。而在這個過程中,可能會拋出一個用戶自定義的異常。異常的拋出,將會使兩個操作回滾。 

    Step1:創建數據庫表 account、stock
    Step2:創建實體類 Account 與 Stock (略)
    Step3:定義 Dao 接口  IAccountDao 與 IStockDao 

複製代碼
1 package com.tongji.dao;
2 
3 public interface IAccountDao {
4 
5     void insertAccount(String aname, double money);
6 
7     void updateAccount(String aname, double money, boolean isBuy);
8 
9 }
複製代碼
複製代碼
1 package com.tongji.dao;
2 
3 public interface IStockDao {
4 
5     void insertStock(String sname, int amount);
6 
7     void updateStock(String sname, int amount, boolean isBuy);
8 
9 }
複製代碼

    Step4:定義 Dao 實現類 AccountDaoImpl 與 StockDaoImpl

複製代碼
 1 package com.tongji.dao;
 2 
 3 import org.springframework.jdbc.core.support.JdbcDaoSupport;
 4 
 5 public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao {
 6 
 7     @Override
 8     public void insertAccount(String aname, double money) {
 9         String sql = "insert into account(aname, balance) values(?,?)";
10         this.getJdbcTemplate().update(sql, aname, money);
11     }
12 
13     @Override
14     public void updateAccount(String aname, double money, boolean isBuy) {
15         String sql = "update account set balance=balance+? where aname=?";
16         if (isBuy) {
17             sql = "update account set balance=balance-? where aname=?";
18         }
19         this.getJdbcTemplate().update(sql, money, aname);
20         
21     }
22 
23 }
複製代碼
複製代碼
 1 package com.tongji.dao;
 2 
 3 import org.springframework.jdbc.core.support.JdbcDaoSupport;
 4 
 5 public class StockDaoImpl extends JdbcDaoSupport implements IStockDao {
 6 
 7     @Override
 8     public void insertStock(String sname, int amount) {
 9         String sql = "insert into stock(sname, count) values (?,?)";
10         this.getJdbcTemplate().update(sql , sname, amount);
11     }
12 
13     @Override
14     public void updateStock(String sname, int amount, boolean isBuy) {
15         //isBuy爲true,則表示購買股票,此時應增加股票賬戶中的股票數量
16         String sql = "update stock set count=count-? where sname=?";
17         if (isBuy) {
18             sql = "update stock set count=count+? where sname=?";
19         }
20         this.getJdbcTemplate().update(sql, amount, sname);
21     }
22 
23 }
複製代碼

    Step5:定義異常類 StockException

複製代碼
 1 package com.tongji.beans;
 2 
 3 public class StockException extends Exception {
 4     private static final long serialVersionUID = 5377570098437361228L;
 5 
 6     public StockException() {
 7         super();
 8     }
 9 
10     public StockException(String message) {
11         super(message);
12     }
13     
14 }
複製代碼

    Step6:定義 Service 接口 IStockProcessService

複製代碼
1 package com.tongji.service;
2 
3 public interface IStockProcessService {
4     void openAccount(String aname, double money);
5     void openStock(String sname, int amount);
6     void buyStock(String aname, double money, String sname, int amount);
7 }
複製代碼

    Step7:定義 service 的實現類 StockProcessServiceImpl

複製代碼
 1 package com.tongji.service;
 2 
 3 import org.springframework.transaction.annotation.Isolation;
 4 import org.springframework.transaction.annotation.Propagation;
 5 import org.springframework.transaction.annotation.Transactional;
 6 
 7 import com.tongji.beans.StockException;
 8 import com.tongji.dao.IAccountDao;
 9 import com.tongji.dao.IStockDao;
10 
11 public class StockProcessServiceImpl implements IStockProcessService{
12      private IAccountDao accountDao;
13      private IStockDao stockDao;
14     
15     public void setAccountDao(IAccountDao accountDao) {
16         this.accountDao = accountDao;
17     }
18 
19     public void setStockDao(IStockDao stockDao) {
20         this.stockDao = stockDao;
21     }
22 
23     @Override
24     public void openAccount(String aname, double money) {
25         accountDao.insertAccount(aname, money);
26     }
27 
28     @Override
29     public void openStock(String sname, int amount) {
30         stockDao.insertStock(sname, amount);
31     }
32 
33     @Override
34     public void buyStock(String aname, double money, String sname, int amount) throws StockException {
35         boolean isBuy = true;
36         accountDao.updateAccount(aname, money, isBuy);
37         //故意拋出異常
38         if (true) {
39             throw new StockException("購買股票異常");
40         }
41         stockDao.updateStock(sname, amount, isBuy);
42     }
43 
44 }
複製代碼

    Step8:定義Spring 配置文件 

複製代碼
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
 5         http://www.springframework.org/schema/beans 
 6         http://www.springframework.org/schema/beans/spring-beans.xsd
 7         http://www.springframework.org/schema/context 
 8         http://www.springframework.org/schema/context/spring-context.xsd">
 9     
10     <!-- 註冊數據源:C3P0數據源 -->
11     <bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
12         <property name="driverClass" value="${jdbc.driverClass}" />
13         <property name="jdbcUrl" value="${jdbc.url}" />
14         <property name="user" value="${jdbc.user}" />
15         <property name="password" value="${jdbc.password}" />
16     </bean>
17     
18     <!-- 註冊JDBC屬性文件 -->
19     <context:property-placeholder location="classpath:jdbc.properties"/>
20     
21     <!-- 註冊Dao -->
22     <bean id="accountDao" class="com.tongji.dao.AccountDaoImpl">
23         <property name="dataSource" ref="myDataSource"/>
24     </bean>
25     <bean id="stockDao" class="com.tongji.dao.StockDaoImpl">
26         <property name="dataSource" ref="myDataSource"/>
27     </bean>
28     <!-- 註冊Service -->
29     <bean id="stockService" class="com.tongji.service.StockProcessServiceImpl">
30         <property name="accountDao" ref="accountDao"/>
31         <property name="stockDao" ref="stockDao"/>
32     </bean>    
33 </beans>
複製代碼

    Step9:測試類

複製代碼
 1 package com.tongji.test;
 2 
 3 import org.junit.Before;
 4 import org.junit.Test;
 5 import org.springframework.context.ApplicationContext;
 6 import org.springframework.context.support.ClassPathXmlApplicationContext;
 7 
 8 import com.tongji.service.IStockProcessService;
 9 
10 public class MyTest {
11     
12     private IStockProcessService service;
13 
14     @Before
15     public void before() {
16         //創建容器
17         @SuppressWarnings("resource")
18         ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
19         service = (IStockProcessService) ac.getBean("stockService");
20     }
21     
22     @Test
23     public void testOpen() {
24         service.openAccount("張三", 10000);
25         service.openStock("華爲", 5);
26     }
27     
28     @Test
29     public void testBuyStock() {
30         service.buyStock("張三", 2000, "華爲", 5);
31     }
32     
33 }
複製代碼

    此配置文件沒有采用事務管理,所以購買股票的時候,出現了數據庫中賬戶金額減少了,但是股票數目沒有增加的不一致情況。

  

  使用 Spring 的事務代理工廠管理事務:

    該方式是,需要爲目標類,即 Service 的實現類創建事務代理。事務代理使用的類是TransactionProxyFactoryBean,該類需要初始化如下一些屬性: 
      (1)transactionManager:事務管理器 
      (2)target:目標對象,即 Service 實現類對象 
      (3)transactionAttributes:事務屬性設置 
      對於 XML 配置代理方式實現事務管理時,受查異常的回滾方式,程序員可以通過以下方式進行設置:通過“-異常”方式,可使發生指定的異常時事務回滾;通過“+異常”方式,可使發生指定的異常時事務提交。

    修改Spring配置文件:

複製代碼
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
 5         http://www.springframework.org/schema/beans 
 6         http://www.springframework.org/schema/beans/spring-beans.xsd
 7         http://www.springframework.org/schema/context 
 8         http://www.springframework.org/schema/context/spring-context.xsd">
 9     
10     <!-- 註冊數據源:C3P0數據源 -->
11     <bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
12         <property name="driverClass" value="${jdbc.driverClass}" />
13         <property name="jdbcUrl" value="${jdbc.url}" />
14         <property name="user" value="${jdbc.user}" />
15         <property name="password" value="${jdbc.password}" />
16     </bean>
17     
18     <!-- 註冊JDBC屬性文件 -->
19     <context:property-placeholder location="classpath:jdbc.properties"/>
20     
21     <!-- 註冊Dao -->
22     <bean id="accountDao" class="com.tongji.dao.AccountDaoImpl">
23         <property name="dataSource" ref="myDataSource"/>
24     </bean>
25     <bean id="stockDao" class="com.tongji.dao.StockDaoImpl">
26         <property name="dataSource" ref="myDataSource"/>
27     </bean>
28     <!-- 註冊Service -->
29     <bean id="stockService" class="com.tongji.service.StockProcessServiceImpl">
30         <property name="accountDao" ref="accountDao"/>
31         <property name="stockDao" ref="stockDao"/>
32     </bean>    
33     
34     <!-- 事務 -->
35     <!-- 註冊事務管理器 -->
36     <bean id="myTxManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
37         <property name="dataSource" ref="myDataSource"/>
38     </bean>
39     <!-- 生成事務代理 -->
40     <bean id="stockServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
41         <property name="transactionManager" ref="myTxManager"/>
42         <property name="target" ref="stockService"/>
43         <property name="transactionAttributes">
44             <props>
45                 <prop key="open*">ISOLATION_DEFAULT,PROPAGATION_REQUIRED</prop>
46                 <prop key="buyStock">ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-StockException</prop>
47             </props>
48         </property>
49     </bean>
50 </beans>
複製代碼

    由於本項目使用的是 JDBC 進行持久化,所以使用 DataSourceTransactionManager 類作爲事務管理器。

    修改測試類:

     public void before() {
           //創建容器
           @SuppressWarnings("resource")
           ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
           service = (IStockProcessService) ac.getBean("stockServiceProxy");
       }

 

  使用 Spring 的事務註解管理事務:
    通過@Transactional 註解方式,也可將事務織入到相應方法中。而使用註解方式,只需在配置文件中加入一個 tx 標籤,以告訴 spring 使用註解來完成事務的織入。該標籤只需指定一個屬性,事務管理器。

    修改Spring配置文件:

複製代碼
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4         xmlns:context="http://www.springframework.org/schema/context"
 5         xmlns:aop="http://www.springframework.org/schema/aop"
 6         xmlns:tx="http://www.springframework.org/schema/tx" 
 7         xsi:schemaLocation="
 8         http://www.springframework.org/schema/beans 
 9         http://www.springframework.org/schema/beans/spring-beans.xsd
10         http://www.springframework.org/schema/context 
11         http://www.springframework.org/schema/context/spring-context.xsd
12         http://www.springframework.org/schema/tx 
13         http://www.springframework.org/schema/tx/spring-tx.xsd
14         http://www.springframework.org/schema/aop 
15         http://www.springframework.org/schema/aop/spring-aop.xsd">
16     
17     <!-- 註冊數據源:C3P0數據源 -->
18     <bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
19         <property name="driverClass" value="${jdbc.driverClass}" />
20         <property name="jdbcUrl" value="${jdbc.url}" />
21         <property name="user" value="${jdbc.user}" />
22         <property name="password" value="${jdbc.password}" />
23     </bean>
24     
25     <!-- 註冊JDBC屬性文件 -->
26     <context:property-placeholder location="classpath:jdbc.properties"/>
27     
28     <!-- 註冊Dao -->
29     <bean id="accountDao" class="com.tongji.dao.AccountDaoImpl">
30         <property name="dataSource" ref="myDataSource"/>
31     </bean>
32     <bean id="stockDao" class="com.tongji.dao.StockDaoImpl">
33         <property name="dataSource" ref="myDataSource"/>
34     </bean>
35     <!-- 註冊Service -->
36     <bean id="stockService" class="com.tongji.service.StockProcessServiceImpl">
37         <property name="accountDao" ref="accountDao"/>
38         <property name="stockDao" ref="stockDao"/>
39     </bean>    
40     
41     <!-- 事務 -->
42     <!-- 註冊事務管理器 -->
43     <bean id="myTxManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
44         <property name="dataSource" ref="myDataSource"/>
45     </bean>
46     <!-- 開啓註解驅動 -->
47     <tx:annotation-driven transaction-manager="myTxManager"/>
48 </beans>
複製代碼

    修改 service 的實現類 StockProcessServiceImpl:

複製代碼
 1 package com.tongji.service;
 2 
 3 import org.springframework.transaction.annotation.Isolation;
 4 import org.springframework.transaction.annotation.Propagation;
 5 import org.springframework.transaction.annotation.Transactional;
 6 
 7 import com.tongji.beans.StockException;
 8 import com.tongji.dao.IAccountDao;
 9 import com.tongji.dao.IStockDao;
10 
11 public class StockProcessServiceImpl implements IStockProcessService{
12      private IAccountDao accountDao;
13      private IStockDao stockDao;
14     
15     public void setAccountDao(IAccountDao accountDao) {
16         this.accountDao = accountDao;
17     }
18 
19     public void setStockDao(IStockDao stockDao) {
20         this.stockDao = stockDao;
21     }
22 
23     @Override
24     @Transactional(isolation=Isolation.DEFAULT, propagation=Propagation.REQUIRED)
25     public void openAccount(String aname, double money) {
26         accountDao.insertAccount(aname, money);
27     }
28 
29     @Override
30     @Transactional(isolation=Isolation.DEFAULT, propagation=Propagation.REQUIRED)
31     public void openStock(String sname, int amount) {
32         stockDao.insertStock(sname, amount);
33     }
34 
35     @Override
36     @Transactional(isolation=Isolation.DEFAULT, propagation=Propagation.REQUIRED, rollbackFor=StockException.class)
37     public void buyStock(String aname, double money, String sname, int amount) throws StockException {
38         boolean isBuy = true;
39         accountDao.updateAccount(aname, money, isBuy);
40         if (true) {
41             throw new StockException("購買股票異常");
42         }
43         stockDao.updateStock(sname, amount, isBuy);
44     }
45 
46 }
複製代碼

    @Transactional 的所有可選屬性如下所示: 
      propagation:用於設置事務傳播屬性。該屬性類型爲 Propagation 枚舉,默認值爲Propagation.REQUIRED。 
      isolation:用於設置事務的隔離級別。該屬性類型爲 Isolation 枚舉,默認值爲Isolation.DEFAULT。 
      readOnly:用於設置該方法對數據庫的操作是否是隻讀的。該屬性爲 boolean,默認值爲 false。 
      timeout:用於設置本操作與數據庫連接的超時時限。單位爲秒,類型爲 int,默認值爲-1,即沒有時限。 
      rollbackFor:指定需要回滾的異常類。類型爲 Class[],默認值爲空數組。當然,若只有一個異常類時,可以不使用數組。 
      rollbackForClassName:指定需要回滾的異常類類名。類型爲 String[],默認值爲空數組。當然,若只有一個異常類時,可以不使用數組。 
      noRollbackFor:指定不需要回滾的異常類。類型爲 Class[],默認值爲空數組。當然,若只有一個異常類時,可以不使用數組。 
      noRollbackForClassName:指定不需要回滾的異常類類名。類型爲 String[],默認值爲空數組。當然,若只有一個異常類時,可以不使用數組。 
     需要注意的是,@Transactional 若用在方法上,只能用於 public 方法上。對於其他非public 方法,如果加上了註解@Transactional,雖然 Spring 不會報錯,但不會將指定事務織入到該方法中。因爲 Spring 會忽略掉所有非 public 方法上的@Transaction 註解。  
    若@Transaction 註解在類上,則表示該類上所有的方法均將在執行時織入事務。 

  使用 AspectJ 的 AOP 配置管理事務(重點):

    使用 XML 配置事務代理的方式的不足是,每個目標類都需要配置事務代理。當目標類較多,配置文件會變得非常臃腫。使用 XML 配置顧問方式可以自動爲每個符合切入點表達式的類生成事務代理。

    修改Spring配置文件:

複製代碼
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4         xmlns:context="http://www.springframework.org/schema/context"
 5         xmlns:aop="http://www.springframework.org/schema/aop"
 6         xmlns:tx="http://www.springframework.org/schema/tx" 
 7         xsi:schemaLocation="
 8         http://www.springframework.org/schema/beans 
 9         http://www.springframework.org/schema/beans/spring-beans.xsd
10         http://www.springframework.org/schema/context 
11         http://www.springframework.org/schema/context/spring-context.xsd
12         http://www.springframework.org/schema/tx 
13         http://www.springframework.org/schema/tx/spring-tx.xsd
14         http://www.springframework.org/schema/aop 
15         http://www.springframework.org/schema/aop/spring-aop.xsd">
16     
17     <!-- 註冊數據源:C3P0數據源 -->
18     <bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
19         <property name="driverClass" value="${jdbc.driverClass}" />
20         <property name="jdbcUrl" value="${jdbc.url}" />
21         <property name="user" value="${jdbc.user}" />
22         <property name="password" value="${jdbc.password}" />
23     </bean>
24     
25     <!-- 註冊JDBC屬性文件 -->
26     <context:property-placeholder location="classpath:jdbc.properties"/>
27     
28     <!-- 註冊Dao -->
29     <bean id="accountDao" class="com.tongji.dao.AccountDaoImpl">
30         <property name="dataSource" ref="myDataSource"/>
31     </bean>
32     <bean id="stockDao" class="com.tongji.dao.StockDaoImpl">
33         <property name="dataSource" ref="myDataSource"/>
34     </bean>
35     <!-- 註冊Service -->
36     <bean id="stockService" class="com.tongji.service.StockProcessServiceImpl">
37         <property name="accountDao" ref="accountDao"/>
38         <property name="stockDao" ref="stockDao"/>
39     </bean>    
40     
41     <!-- 事務 -->
42     <!-- 註冊事務管理器 -->
43     <bean id="myTxManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
44         <property name="dataSource" ref="myDataSource"/>
45     </bean>
46     <!-- 註冊事務通知 -->
47     <tx:advice id="txAdvice" transaction-manager="myTxManager">
48         <tx:attributes>
49             <!-- 指定在連接點方法上應用的事務屬性 -->
50             <tx:method name="open*" isolation="DEFAULT" propagation="REQUIRED"/>
51             <tx:method name="buyStock" isolation="DEFAULT" propagation="REQUIRED" rollback-for="StockException"/>
52         </tx:attributes>
53     </tx:advice>
54     
55     <!-- AOP配置 -->
56     <aop:config>
57         <!-- 指定切入點 -->
58         <aop:pointcut expression="execution(* *..service.*.*(..))" id="stockPointCut"/>
59         <aop:advisor advice-ref="txAdvice" pointcut-ref="stockPointCut"/>
60     </aop:config>
61 </beans>
複製代碼

  總結:Spring 的事務管理,是 AOP 的應用,將事務作爲切面織入到了 Service 層的業務方法中。

轉載至:https://www.cnblogs.com/qjjazry/p/6366204.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章