英文:
Is good practice to inject Transactional service to another transactional service in Spring?
问题
我感到困惑。我发现了关于将@Service
类注入到另一个@Service
类中的帖子。但是如果这两个类都有@Transactional
注解呢?@Transactional
会产生影响,或者更好的做法是注入repositories吗?
简单示例:
@Transactional
@Service
public class BBBServiceImpl implements BBBService {
private final BBBRepository bbbRepository;
// @Autowired 构造函数,方法等...
}
第二个类:
@Transactional
@Service
public class AAAServiceImpl implements AAAService {
private final AAARepository aaaRepository;
private final BBBService bbbService;
@Autowired
public AAAServiceImpl(AAARepository aaaRepository, BBBService bbbService) {
this.aaaRepository = aaaRepository;
this.bbbService = bbbService;
}
// 方法等...
}
或者更好的解决方案是:
@Transactional
@Service
public class AAAServiceImpl implements AAAService {
private final AAARepository aaaRepository;
private final BBBRepository bbbRepository;
@Autowired
public AAAServiceImpl(AAARepository aaaRepository, BBBRepository bbbRepository) {
this.aaaRepository = aaaRepository;
this.bbbRepository= bbbRepository;
}
// 方法等...
}
英文:
I'm in consternation. I found posts about inject @Service
class to another @Service
class. But what if the both classes have @Transactional
annotation? @Transactional
makes a difference or maybe better practise is inject repositories?
Simple exmaple:
@Transactional
@Service
public class BBBServiceImpl implements BBBService {
private final BBBRepository bbbRepository;
// @Autowired constructor, methods etc...
}
second class:
@Transactional
@Service
public class AAAServiceImpl implements AAAService {
private final AAARepository aaaRepository;
private final BBBService bbbService;
@Autowired
public AAAServiceImpl(AAARepository aaaRepository, BBBService bbbService) {
this.aaaRepository = aaaRepository;
this.bbbService = bbbService;
}
// methods etc...
}
Or better solution is:
@Transactional
@Service
public class AAAServiceImpl implements AAAService {
private final AAARepository aaaRepository;
private final BBBRepository bbbRepository;
@Autowired
public AAAServiceImpl(AAARepository aaaRepository, BBBRepository bbbRepository) {
this.aaaRepository = aaaRepository;
this.bbbRepository= bbbRepository;
}
// methods etc...
}
答案1
得分: 3
一般来说,_类_不应该是事务性的,而是它们的方法应该是。如果涉及的内容需要事务性,您应该应用 @Transactional
。有时这意味着您将组合多个级别,因为您可以看到即使从个别来看,这些部分也需要 @Transactional
。有时这意味着堆栈中只有一个级别需要它。您必须根据软件的逻辑要求来确定。
适用 @Transactional
的一种情况是当您有一个协调订单发货的服务时;标记订单发货的更新和写入包裹信息应该在事务中完成。因此,OrderHandlingService#shipParcel
应该是 @Transactional
,而且涉及数据处理的任何方法也应该是。
英文:
In general, classes shouldn't be transactional but rather their methods. You should apply @Transactional
if the item concerned needs transactionality. Sometimes this means that you'll compose multiple levels, because you can see that even individually the pieces need @Transactional
. Sometimes it means that only one level in the stack needs it. You must determine based on the logical requirements of your software.
A case where it makes sense to apply @Transactional
is where you have a service that coordinates shipment of orders; the updates to mark the order shipped and to write the parcel information should happen transactionally. Therefore, OrderHandlingService#shipParcel
should be @Transactional
, and so should any methods involving data handling.
答案2
得分: 1
理想情况下,**管理器(Manager)**代表着您的业务逻辑,因此应该使用@Transactional
进行注解。
服务层可能会调用不同的DAO来执行数据库操作。假设您在一个服务方法中有3个DAO操作。如果您的第一个DAO操作失败,其他两个操作可能仍会继续执行,这将导致不一致的数据库状态。对服务层进行注解可以避免这种情况。
这还取决于传播和隔离级别
的值。
即使您想要继续使用相同的事务,但在服务B中,它的传播级别是**Propagation.REQUIRES_NEW
**,它将创建一个新的事务并执行业务。
英文:
Ideally, Service layer (Manager) represents your business logic and hence it should be annotated with @Transactional
.
Service layer may call different DAOs to perform DB operations. Lets assume a situation where you have 3 DAO operations in a service method. If your 1st DAO operation failed, other two may be still passed and you will end up with an inconsistent DB state. Annotating Service layer can save you from such situations.
Also it's depends on Propagation and Isolation
values as well.
Even though you want to continue with same transaction but on service B it's Propagation is Propagation.REQUIRES_NEW
it will create new transaction and perform business.
答案3
得分: 0
可以的。因为你可以在一个服务内部调用另一个服务,无论它是否是事务性的都可以。没有问题,并且是推荐的做法。
英文:
Yes you can. Since you can call another service inside a service even it is transactional or not. No problem & recommended
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论