关于springboot:Spring-Boot-如果一个service-Transactional所在方法不是public会发生什么二

由Spring Boot 如果一个service @Transactional所在办法不是public会产生什么?咱们能够晓得,当一个servie 中被@Transactional润饰的办法全部都是no-public的时候,Spring不会创立代理类,也就是咱们的事务没有方法失效~。

那要是@Transactional润饰的办法有no-public,也有public的时候呢?这种状况下,spring 也是会创立代理类的。那么问题来了,如果这个public办法 调用了一个no-public 办法呢?有两种状况:

1. 这个no-public 办法上有一个帽子(@Transactional);
2. 这个no-public 办法上没有帽子;

上面详细分析:
图1

    final void testSaveAd() {
        try {
            MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
            if (var10000 == null) {
                CGLIB$BIND_CALLBACKS(this);
                var10000 = this.CGLIB$CALLBACK_0;
            }

            if (var10000 != null) {
                var10000.intercept(this, CGLIB$testSaveAd$0$Method, CGLIB$emptyArgs, CGLIB$testSaveAd$0$Proxy);
            } else {
                super.testSaveAd();
            }
        } catch (Error | RuntimeException var1) {
            throw var1;
        } catch (Throwable var2) {
            throw new UndeclaredThrowableException(var2);
        }
    }
    public final void testSaveAd2() {
        try {
            MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
            if (var10000 == null) {
                CGLIB$BIND_CALLBACKS(this);
                var10000 = this.CGLIB$CALLBACK_0;
            }

            if (var10000 != null) {
                var10000.intercept(this, CGLIB$testSaveAd2$1$Method, CGLIB$emptyArgs, CGLIB$testSaveAd2$1$Proxy);
            } else {
                super.testSaveAd2();
            }
        } catch (Error | RuntimeException var1) {
            throw var1;
        } catch (Throwable var2) {
            throw new UndeclaredThrowableException(var2);
        }
    }
    final void save() {
        try {
            MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
            if (var10000 == null) {
                CGLIB$BIND_CALLBACKS(this);
                var10000 = this.CGLIB$CALLBACK_0;
            }

            if (var10000 != null) {
                var10000.intercept(this, CGLIB$save$2$Method, CGLIB$emptyArgs, CGLIB$save$2$Proxy);
            } else {
                super.save();
            }
        } catch (Error | RuntimeException var1) {
            throw var1;
        } catch (Throwable var2) {
            throw new UndeclaredThrowableException(var2);
        }
    }

下面三段code,别离是代理类对咱们定义的三个办法进行增强解决的状况;

@SpringBootTest
@RunWith(SpringRunner.class)
public class TransactionTest {
    @Autowired
    private TransactionServiceTest transactionServiceTest;

    @Test
    public void tansTest() {
        transactionServiceTest.testSaveAd2();
    }
}

运行下面的测试用例控制台没有输入 “commit” 的字眼

来,换一个测试姿态:

import java.lang.reflect.Method;

@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class TransactionTest {
    @Autowired
    private TransactionServiceTest transactionServiceTest;
    
    @Transactional(rollbackFor = Exception.class)
    @Test
    public void tansTest2() throws Exception {
        invokeMethod(transactionServiceTest,"testSaveAd",null,null);
    }

    public static Object invokeMethod(Object owner,String methodName,Class[] argsClass,Object[] args) throws Exception{
        Object objRtn = null;
        Class ownerClass = owner.getClass();
        Method method = ownerClass.getDeclaredMethod(methodName, null);
        //Method method = ownerClass.getMethod(methodName, argsClass);
        method.setAccessible(true);
        method.invoke(owner, args);
    }
    
}

上面是日志输入:

Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6904f5a0]

oh,no 呈现了扎眼了 “commit”。这是为什么呢?

图2

看到了吗,TransactionServiceTest的实例不是代理类,因而事务也就生效了!

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理