玩转Spring全家桶-Spring的事务抽象

​ 丁雪丰老师在《玩转Spring全家桶》中第二章Spring的事务抽象中的示例地址:https://github.com/digitalsonic/geektime-spring-family/tree/master/Chapter%202/declarative-transaction-demo,感兴趣的朋友可以下载运行,使用的H2数据库,无需更改配置直接运行。

​ 主要是下面三个方法:

package geektime.spring.data.declarativetransactiondemo;

import com.stark.commons.spring.core.context.ApplicationContextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Component
public class FooServiceImpl implements FooService {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    @Transactional
    public void insertRecord() {
        jdbcTemplate.execute("INSERT INTO FOO (BAR) VALUES ('AAA')");
    }

    @Override
    @Transactional(rollbackFor = RollbackException.class)
    public void insertThenRollback() throws RollbackException {
        jdbcTemplate.execute("INSERT INTO FOO (BAR) VALUES ('BBB')");
        throw new RollbackException();
    }

    @Override
    public void invokeInsertThenRollback() throws RollbackException {
        insertThenRollback();
    }
}

​ 其中invokeInsertThenRollback()方法内部调用了insertThenRollback()方法,但是事务并没有被回滚,因为其走的是内部调用,而Spring实现声明式事务依赖的是代理和增强,代理在运行时会截获对被注解方法的调用,并在方法调用前后添加事务管理的逻辑(例如开启、提交或回滚事务)。内部调用不会调用代理对象的方法,因此事务无效。详细可看org.springframework.transaction.interceptor.TransactionAspectSupport类中invokeWithinTransaction方法。需要以下依赖:

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>

​ 在实际环境中,可通过如下方式完善:

1、在pom.xml中新增依赖

			<dependency>
				<groupId>com.stark.commons</groupId>
				<artifactId>commons-spring-core</artifactId>
				<version>1.2.0-SNAPSHOT</version>
			</dependency>

2、在serviceImpl中新增方法

    private FooServiceImpl getThis() {
        return ApplicationContextUtil.getBean("fooService", FooServiceImpl.class);
    }

3、修改内部调用

    @Override
    public void invokeInsertThenRollback() throws RollbackException {
        getThis().insertThenRollback();
    }

​ 这样会发现事务仍然进行了回滚,原理是通过 ApplicationContextUtil.getBean() 方法获取 Bean,是从 Spring 容器中获取实际的代理对象,可以确保在方法调用时能够正确的应用事务代理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值