@Transactional在如下自调用场景下会失效
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao = null;
// 传播行为定义为REQUIRED
@Override
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED,timeout = 1)
public int insertUsers(List<User> userList) {
int count=0;
for (User user:userList
) {
// 调用自己的方法,产生自调用问题
count+=this.insertUser(user);
}
return count;
}
// 传播行为定义为REQUIRES_NEW,每次调用产生新事务
@Override
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRES_NEW,timeout = 1)
public int insertUser(User user) {
return userDao.insertUser(user);
}
}
问题:
我们知道Spring数据库事务是通过Spring AOP实现的,而AOP的原理是使用动态代理模式实现,在自调用的过程中,是类自身的调用,而不是代理对像去调用,所以就不会将事务织入我们的流程中。为了解决这个问题,我们用Service去调用另外一个Service,这样就是代理对象的调用。如下:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao = null;
private ApplicationContext applicationContext=null;
// 实现生命周期方法,设置IoC容器
@Override
public void setApplicationContext(ApplicationContext applicationContext)throws BeansException{
this.applicationContext=applicationContext;
}
// 传播行为定义为REQUIRED
@Override
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED,timeout = 1)
public int insertUsers(List<User> userList) {
int count=0;
UserService userService=applicationContext.getBean(UserService.class);
for (User user:userList
) {
// 使用获取到的代理对象调用方法
count+=userService.insertUser(user);
}
return count;
}
// 传播行为定义为REQUIRES_NEW,每次调用产生新事务
@Override
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRES_NEW,timeout = 1)
public int insertUser(User user) {
return userDao.insertUser(user);
}
}
以上部分内容参考《深入浅出SpringBoot2.X》