spring怎么在一个事务中开启另一个事务

上面提到的情景可能不常见,但是还是会有的,一旦遇到,如果业务比较复杂,就会很麻烦,但是还是有解决的方案的,比如将一个service方法拆成两个方法,也就是将两个操作的事务分开,但是这只适用与业务比较简单的,如果出现多次数据库的写操作,而我们调用的系统只需要其中一个写操作的最新数据,如果我们将它分开,那么如果调用目标系统出现异常的时候,那么之前的写操作就不能回滚了。

举个简单的例子:

@Service
public class ServiceA {

	@Transactional
	public void doSomething(){
		
		向数据库中添加数据;
		
		调用其他系统;
	}
}

这里就用伪代码来做示例了,当我们执行了“向数据库中添加数据”,我们去数据库中查询,发现并没有我们添加的数据,但是当我们的service这个方法执行完成之后,数据库中就有这条数据了,这是由于数据库的隔离性造成的。

spring中的事务注解@transactional提供了一个参数:

Propagation propagation() default Propagation.REQUIRED;

这个参数是定义spring事务的传递性的,默认值为required,也就是如果有事务,就加入事务,如果没有,就创建事务。这个参数的值有很多,例如REQUIRES_NEW,这个值就代表创建一个新的事务,与原来的事务分开。这个好像能解决我们的问题。

我们将刚刚那个方法修改一下:

@Service
public class ServiceA {

	@Transactional
	public void doSomething(){
		
		insert();
		
		调用其他系统;
	}
	
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void insert(){
		向数据库中添加数据;
	}
}

执行之后,发现结果还是没有改变,必须要整体执行完成,数据库中数据才会出现,说明还是在一个事务中。

我们再将代码修改一下:

@Service
public class ServiceA {

	@Autowired
	private ServiceB serviceB;
	@Transactional
	public void doSomething(){
		
		serviceB.insert();
		
		调用其他系统;
	}
}
@Service
public class ServiceB {

	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void insert(){
		向数据库中添加数据;
	}
}

我们将要事务分离出来的方法写在另一个service中,再次测试,发现执行完插入语句之后,数据库中就已经能查到数据了,说明事务分离了,完成了我们的需求。

当然spring其实也考虑这个,在spring的配置中,我们只需要添加标签 <aop:aspectj-autoproxy expose-proxy="true"/> 或者 <aop:config expose-proxy="true"> ,并且在代码的调用中要求使用代理对象去调用即可:

((ServiceA ) AopContext.currentProxy()).insert();

转载于:https://my.oschina.net/u/3441184/blog/893628

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot 项目开启声明式事务管理,可以通过以下步骤实现: 1. 在 pom.xml 文件添加 Spring Boot Starter JDBC 或 Spring Boot Starter Data JPA,这两个依赖都包含了 Spring JDBC 和 Spring ORM 模块。 2. 在application.properties或application.yml文件配置数据源相关信息,如数据库连接地址、用户名、密码等。 3. 在启动类上添加 @EnableTransactionManagement 注解,启用 Spring 的声明式事务管理功能。 4. 在需要开启事务的方法上添加 @Transactional 注解,即可将该方法纳入到事务管理。 示例代码如下: ```java @SpringBootApplication @EnableTransactionManagement public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } } @Service public class MyService { @Autowired private MyRepository myRepository; @Transactional public void save(MyEntity entity) { myRepository.save(entity); } } @Repository public class MyRepository { @Autowired private JdbcTemplate jdbcTemplate; public void save(MyEntity entity) { jdbcTemplate.update("insert into my_table (name, age) values (?, ?)", entity.getName(), entity.getAge()); } } ``` 在上面的示例代码,我们使用了 Spring Boot Starter JDBC 依赖,并在启动类上添加了 @EnableTransactionManagement 注解,表示启用 Spring 的声明式事务管理功能。在 MyService 类的 save 方法上添加了 @Transactional 注解,表示该方法需要开启事务管理。在 MyRepository 类,我们使用了 JdbcTemplate 对数据库进行操作,JdbcTemplate 会自动参与到 Spring事务管理

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值