先简单说一下情况:今天写代码的时候遇到了一个坑,一个类里面的A方法存在一个事务,之后A方法调用该类的B方法,B方法里面又通过RPC调用另一个微服务的C方法,C方法自己有事务且他们都是通过ID去修改同一条数据.,这就出现了经典死锁,见代码
public class Test{
@Autowired
private UserDao userDao;
@Autowired
private UserHsfService userHsfService;
@Transactional
public void A(){
User user = new User();
user.setId("123");
user.setName("张三");
userDao.updateById(user);
B(user);
}
public void B(User user){
/*这里有的同学一定会说,同一个类里面如果出现了
方法间调用事务不生效.
说的没错但是这里是通过hsf调用另个微服务的方法,
所以该方法有事务的话是可以生效的
*/
userHsfService.updateById(user);
}
}
public class UserHsfServiceImpl
implements UserHsfService{
@Autowired
private UserDao userDao;
@Transactional
public void updateById(User user){
userDao.updateById(user);
}
}
解析:因为Test类里面的A方法是一个事务,Hsf里面的updateById
又是另一个事务,且A方法里面的事务还没有关闭(因为当前被
@Transactional注释的方法还没执行结束),这时A方法的更具ID
修改会将该条数据加上行级锁,之后Hsf里面的updateById在等待
上一个事务释放行级锁A方法在等待调用的Hsf执行完成这就出现
了死锁.当Test类里面调用的Hsf超时后A方法事务回滚,行级锁释
放Hsf里面的Update执行成功.
图解