06_Spring 事物失效

1, 事务注解的方法要用pulbic声明, private声明会失效
理由: CGLIB通过继承方式实现代理类,private方法在子类不可见,自然也就无法进行事务增强

@Transactional
private void createUserPrivate(UserEntity entity) {}

2, 不能调用同类里的事物方法. 必须通过调用事物增强的代理类 的目标方法才能生效。

事务是基于动态代理实现的, 调用类里面的方法 self.createUserPublic() (调用的是UserService.createUserPublic()) 就得不到增强了, 必须要调用代理类的方法才会增强(使用到事物)

  **代理类增强:  开启事物
               目标方法
               提交事物/ 回滚事物** 
public UserService{
	public int createUserWrong2(String name) {
	try {
		this.createUserPublic(new UserEntity(name));
	} catch (Exception ex) {
		log.error("create user failed because {}", ex.getMessage());
	}
		return userRepository.findByName(name).size();
	} 
}


/
/标记了@Transactionalpublic方法
@Transactional
public void createUserPublic(UserEntity entity) {
	userRepository.save(entity);
if (entity.getName().contains("test"))
	throw new RuntimeException("invalid username!");
}

3, try…catch 处理过的异常 不会回滚

//异常无法传播出方法,导致事务无法回滚
@Transactional
public void createUserWrong1(String name) {
try {
	userRepository.save(new UserEntity(name));
	throw new RuntimeException("error");
} catch (Exception ex) {
	log.error("create user failed", ex);
}
}

4, 受检异常回滚 @Transactional(rollbackFor = Exception.class),默认不回滚受检异常

有这么一个场景:一个用户注册的操作,会插入一个主用户到用户表,还会注册一个关联的子用户。我们希望将子用户注册的数据库操作作为一个独立事务来处理,即使失败也不会影响主流程,即不影响主用户的注册。

1, 子用户创建使用开启新事物(propagation = Propagation.REQUIRES_NEW)
2, 在创建用户方法中 子用户创建用try…catch处理异常

@Autowired
private UserRepository userRepository;
@Autowired
private SubUserService subUserService;

@Transactional
public void createUserWrong(UserEntity entity) {
	createMainUser(entity);
	try{
	// 子用户创建, try..catch后出现异常, 主用户创建不会回滚
		subUserService.createSubUserWithExceptionWrong(entity);
	}catch (Exception ex) {
	
	}
} 

private void createMainUser(UserEntity entity) {
	userRepository.save(entity);
	log.info("createMainUser finish");
}

@Service
@Slf4j
public class SubUserService {
	@Autowired
	private UserRepository userRepository;
	
	// (propagation = Propagation.REQUIRES_NEW)必须要开启新的事务, 不然与主用户创建在同一事务中, 会一起回滚
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void createSubUserWithExceptionWrong(UserEntity entity) {
		log.info("createSubUserWithExceptionWrong start");
		userRepository.save(entity);
		throw new RuntimeException("invalid status");
}
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值