1. 程式人生 > >SSM學習記錄(五)——通過註解及AOP進行事務管理

SSM學習記錄(五)——通過註解及AOP進行事務管理

2018.5.4

僅為個人理解 不足之處歡迎指正~

什麼是事務管理?

事務管理是對於一系列資料庫操作進行管理,一個事務包含一個或多個SQL語句,是邏輯管理的工作單元(原子單元)

事務管理的核心在於 回 滾

什麼情況下需要事務管理?

對資料庫中的資料進行批量操作或多表操作時,為了保證資料的正確性和一致性,需要新增事務管理機制進行管理

舉例說明:

銀行轉賬操作細分為兩個步驟:(A向B轉賬100元)

(1)A使用者賬戶餘額減少100元

(2)B使用者賬戶餘額增加100元

那麼假如當執行完(1)步驟而未完成(2)步驟時

情況發生變化 如伺服器宕機 或者使用者取消轉賬

那此時A的餘額減少而B的餘額沒有增加 勢必會造成錯誤

不進行事務管理的情況

由於之前的專案是各種登入註冊之類的業務 較難模擬真實的需要事務管理的操作

我們假想以下操作:

連續註冊兩個使用者 其中第一個使用者合理 第二個使用者的使用者名稱超過了資料庫中定義的最大長度

將這兩個插入過程等價於轉賬中的減少餘額與增加餘額

第二個插入失敗 則第一個插入的結果應該撤銷

在UserService.java中增加一個測試方法:


和他的實現:


編寫Controller接受指令:

package controller;

import javax.annotation.Resource;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import pojo.User;
import service.UserService;

@Controller
public class TestController 
{
	@Resource
	UserService userService;
	@RequestMapping("/shiwuguanli")  
     public ModelAndView shiwuguanli()
    {  
            ModelAndView mv = new ModelAndView("welcome");
            userService.add2User();
            return mv;
      }
}

執行程式並測試:


伺服器報錯 此時檢視資料庫:


發現第一個插入操作完成 第二個未完成

使用註解進行事務管理

第一步:

在spring-mybatis配置檔案中加入:


注:jdbcDataSource為自己配置的資料池名稱

第二步:

在所需事務管理的方法上加註解@Transactional


再次執行測試

頁面同樣報錯,但資料庫中沒有出現任何一條插入資訊

注意點:

1.註解需要加在Service的實現中 而不是介面或其他位置

2.不要使用try catch捕獲異常  這樣將不會進行事務回滾 

若需要捕獲異常又需要事務回滾 推薦使用以下方法:

@Transactional
	@Override
	public void add2User()//事務管理測試
	{
        try
        {
        	User user=new User("放得下","mima1","電話1","郵箱1");
        	User user2=new User("放不下放不下放不下放不下放不下放不下放不下放不下",
            		"mima1","電話1","郵箱1");
        	userdao.addUser(user);
        	userdao.addUser(user2);
        }
		catch(Exception e)
		{
			System.out.println("伺服器異常");
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
		}
    }

通過


手動回滾

頁面不會報錯 資料庫中也不會多出資料

使用AOP進行事務管理

我們將剛才的@Transactional去除

開始使用AOP方式進行事務管理:

在spring-mybatis的配置檔案中加入以下語句:

  <tx:advice id="txAdvice" transaction-manager="transactionManager">
   	<tx:attributes>
   		<tx:method name="add*" propagation="REQUIRED" isolation="DEFAULT"/>
   	</tx:attributes>
   </tx:advice>
   
   <aop:config>
   		<aop:pointcut id="shiwuguanli"
   			expression="execution(* service.UserService.*(..))"/>
   			<aop:advisor advice-ref="txAdvice" pointcut-ref="shiwuguanli"/>
   </aop:config>

其中:


代表“add開頭 任意字尾的方法” 我們之前使用的方法是add2User 所以包含在這之中

<tx:method>中的標籤有很多

name:方法名的匹配模式,通知根據該模式尋找匹配的方法。 
propagation:設定事務定義所用的傳播級別。 
isolation:設定事務的隔離級別。 
timeout:指定事務的超時(秒)。 
read-only:該屬性為true指示事務是隻讀的 
no-rollback-for:以逗號分隔的異常類的列表,目標方法可以跑出這些異常而不會導致通知執行回滾 

rollback-for:以逗號分隔的異常類的列表,當目標方法跑出這些異常時會導致通知執行回滾。預設情況下,該列表為空,因此不在no-rollback-for列表中的任何執行時異常都會導致回滾。 

這裡不做詳細解釋 一般可以採用預設的配置形式


這裡表示的是將剛才的txAdvice織入

在呼叫UserService中所屬的所有方法時會呼叫事務管理 但是要滿足上面的name

執行測試成功 頁面沒有報錯資訊 資料庫中沒有插入資料

同時控制檯輸出了捕獲的異常


其他程式碼:

本文基於之前的各篇SSM學習記錄 其他程式碼沒有做出改動 

專案結構如下:


這一個測試中沒有建立新的view層頁面 僅用瀏覽器指令完成

總結:

本文僅演示了一種簡單的需要事務管理的情景

而事物的四大特徵:原子性、一致性、隔離性、永續性

還可以衍生出其他很多種需要事務管理的情況

尤其是隔離性所要求的 本業務的資料不會受到其他業務的干擾 非常重要

具體情況具體分析

謝謝~