目录
1.在一个bean中,一个无事务的方法调用有事务的方法,事务失效
3.一个有事务的方法调用另一个有事务的方法,如果在第二个方法中出现异常,事务回滚,然后在第一个方法中,没有判断第二个方法的返回值,直接进行事务的提交,这时会报错,因为事务已经回滚了,不能进行提交
1.在一个bean中,一个无事务的方法调用有事务的方法,事务失效
原因是在一个类中调用,使用this调用,this指的是当前原始对象的实例,而非代理对象
解决方法:将要添加事务的方法写在其他bean中,方法上添加事务,然后注入进行进行调用
@Service
public class UserService {
public void methodA() {
// 无事务方法
this.methodB(); // 直接调用,事务失效
}
@Transactional
public void methodB() {
// 有事务方法
// 事务失效原因:this指向原始对象,而不是代理对象
// 解决方案:通过注入的代理对象调用
}
}
// 正确写法
@Service
public class UserService {
@Autowired
private UserService self; // 注入代理对象
public void methodA() {
self.methodB(); // 通过代理对象调用,事务生效
}
@Transactional
public void methodB() {
// 有事务方法
}
}
2.在一个事务中进行数据源的切换不生效
因为开启事务后是不能进行动态数据源的切换的
事务内是不支持进行数据源的切换的,一旦开启事务,这个事务只能对应一个数据源
解决方法:规划好方法的逻辑,不在事务内进行数据源的切换
@Service
public class UserService {
@Autowired
private DataSource dataSource;
@Transactional
public void method() {
// 开启事务
try {
// 业务操作1
// 尝试切换数据源
DynamicDataSourceContextHolder.setDataSource("slave");
// 此时切换数据源不会生效,因为事务已经开启
// 事务会继续使用原来的数据源
// 业务操作2
} finally {
DynamicDataSourceContextHolder.clear();
}
}
}
// 正确写法:在事务方法之前切换数据源
@Service
public class UserService {
@Autowired
private UserService self;
public void method() {
// 先切换数据源
DynamicDataSourceContextHolder.setDataSource("slave");
try {
// 再开启事务
self.transactionalMethod();
} finally {
DynamicDataSourceContextHolder.clear();
}
}
@Transactional
public void transactionalMethod() {
// 事务方法
}
}
3.一个有事务的方法调用另一个有事务的方法,如果在第二个方法中出现异常,事务回滚,然后在第一个方法中,没有判断第二个方法的返回值,直接进行事务的提交,这时会报错,因为事务已经回滚了,不能进行提交
解决方法:可以在第二个方法中开启一个新事物,这样两个事务互补干扰
也可以在第二个方法中不添加事务,直接使用方法一的事务,如果方法二异常,则在方法一中进行判断,进行事务的操作