在java项目中,我们有一个包含许多方法的胖服务类:
@Service
@Transaction
public class FatService {
@Autowired
private FatRepository fatRepository;
public void doSomethingSpecial() {
// complex logic
fatRepository.save(foo);
fatRepository.save(bar);
}
public void doSomething1() {}
public void doSomething2() {}
public void doSomething3() {}
public void doSomething4() {}
public void doSomething5() {}
public void doSomething6() {}
public void doSomething7() {}
public void doSomething8() {}
}
此服务旨在为代码库中的所有类提供事务边界。它有一些数据库操作。如果我们涉及交易,我们只需要维护这个类。
但它很胖,我发现有一些方法仅用于其他一些类,例如doSomethingSpecial()
,仅用于课程Special
:
@Component
class Special {
@Autowired
private FatService fatService;
doSomething() {
// do something first
fatService.doSomethingSpecial();
// do something last
}
}
我不想将逻辑拆分为两个不同的类,因此我将doSomethingSpecial()
方法从FatService
移到Special
:
@Component
class Special {
@Autowired
private FatService fatService;
doSomething() {
// do something first
doSomethingSpecial();
// do something last
}
@Transactional
private doSomethingSpecial() {
// this method is move from FatService
fatService.save(foo);
fatService.save(bar);
}
}
注意我仍然在方法@Transactional
上保留doSomethingSpecial
注释。同时向save
添加FatService
方法:
public void save(Object obj) {
fatRepository.save(obj);
}
但是我的同事说我不应该把它移到Speical
,因为我们必须管理两个不同类的交易,如果交易遍布所有代码库,代码很难维护。
我想知道什么是最佳解决方案?
答案 0 :(得分:2)
基本上,涉及数据库的典型应用程序中的所有内容都是事务性的。因此,除非您的应用程序是一个小型玩具应用程序,否则将每个事务方法放在一个类中是不可管理的:您最终会得到一个包含数百或数千种方法的类。如果你有一个分层应用程序,那么每个服务都应该是事务性的,而且这只需要一个注释,所以没有太多要管理的。
也就是说,你的重构有一个严重的错误:尽管Special.doSomethingSpecial()
方法被注释为事务性的,但它实际上并非如此,因为它是一个直接从同一个类的另一个方法调用的私有方法。因此事务性Spring拦截器无法拦截方法调用并处理事务。简而言之,@Transactional
仅在Spring bean调用另一个 Spring bean时才有效。
答案 1 :(得分:0)