關於srping的AOP事務管理問題,自定義切面是否致使事務控制失效

applicationContext.xml:java

<!-- 方法調用時間記錄 -->
    <bean id="methodExecuteTime" class="com.common.aspect.Aspect" />

    <!-- Spring AOP config (* com.customer.service.*.*(..))中幾個通配符的含義: 第一個 * :通配
        任意返回值類型 第二個 * :通配 包com.customer.service下的任意class 第三個 * :通配 包com.customer.service下的任意class的任意方法
        第四個 .. :通配 方法能夠有0個或多個參數 -->
    <aop:aspectj-autoproxy proxy-target-class="true" expose-proxy="true"/>
    <aop:config proxy-target-class="true">
        <aop:pointcut id="serviceMethods" expression="execution(* com.customer.service..*.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethods" order="2" />

        <!--此處配置使得事務控制 回滾失效 暫時註釋掉-->
        <!-- DB Service log -->
        <aop:aspect id="logThrsysServiceMethodExecuteTime" ref="methodExecuteTime" >
            <aop:pointcut id="thrsysServiceMethods" expression="execution(* com.customer.service..*.*(..))" />
            <aop:around method="methodExecuteTime" pointcut-ref="thrsysServiceMethods" />
        </aop:aspect>
    </aop:config>

當時在一個update開頭的方法中有多個更新數據庫的操做,爲了測試事務回滾的有效性,在代碼中放置了一段空指針異常代碼,發現事務並無回滾。數據庫

註釋掉<!--此處配置使得事務控制 回滾失效 暫時註釋掉-->下的內容,事務正常回滾。當時記得重複驗證了要幾回,事務並無由於異常而回滾,因此才註釋掉了下面的切面
可是後來不知道什麼緣由,放開這個註釋事務也能正常回滾了。沒有找到什麼緣由致使這樣。(不知道是我當時測的時候的問題,仍是後來由於改了什麼東西的緣由致使的,特地在此記錄)。express

package com.common.aspect;

import com.common.util.SensitiveParamUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

@Slf4j
public class Aspect {

    private final static SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public Object methodExecuteTime (ProceedingJoinPoint joinPoint) throws Throwable {
        Object object;
        Date startDate = new Date();
        Signature signature = joinPoint.getSignature();
        MethodSignature ms = (MethodSignature)signature;
        Method method = ms.getMethod();
        Class<?>[] paramTypes = method.getParameterTypes();
        Object[] args = joinPoint.getArgs();
        //訪問目標方法的參數:
        log.info("{} 調用時間:{}",signature.toString(), sdf.format(startDate));
        long start = System.currentTimeMillis();
        object = joinPoint.proceed();
        long end = System.currentTimeMillis();
        String time = formatExecuteTime(end - start);
        log.info("{} 執行時間:{}",signature.toString(), time);
        new Thread(() -> {
            for (int i = 0; i < paramTypes.length; i++) {
                args[i] = SensitiveParamUtils.getJson(args[i]);
            }
            log.info("{} 方法入參{}", signature.toString(), Arrays.toString(args));
        }).start();

        return object;
    }

    private String formatExecuteTime(long executeTime) {
        long min = (executeTime % 3600000) / 60000;
        long sec = (executeTime % 60000) / 1000;
        long msec = executeTime % 10000;
        StringBuilder sb = new StringBuilder();
        if (min > 0) {
            sb.append(min).append("m ");
        }
        if (sec > 0) {
            sb.append(sec).append("s ");
        }
        sb.append(msec).append("ms");
        return sb.toString();
    }
}

單元測試、service自定義寫,在service中加入空指針異常代碼檢測事務回滾的有效性。app

相關文章
相關標籤/搜索