“@Transactional”应该在哪里?放置Service层或DAO
首先,我可能在问一些以前被问过并回答过的问题,但我无法返回搜索结果。我们在服务层定义事务注释,典型的 Spring Hibernate CRUD 通常是
Controller->Manager->Dao->Orm 。
我现在遇到的情况是,我需要根据客户端站点在域模型之间进行选择。 假设客户端 A 正在使用我的域模型,一切都很好,但其他客户端站点会给我提供 Web 服务,而不是使用我们的域模型。
我应该更换哪一层。我相信它必须是 DAO,它将从 Web 服务获取数据并将其发送回来。即两个单独编写的 DAO 层并根据场景插入。
我现在意识到,当我们将 @Transactional
放在 Service 层时,我们一直在做紧耦合(如果有这样的事情或者说没有松耦合)。这么多的大脑不可能是错的,或者确实是这样(我对此表示怀疑)。
所以问题是““@Transactional
”应该放在服务层或 DAO 的哪里?”我应该更换它是向下的服务层吗?
十一年过去了,仍然具有现实意义。如果我回顾这个项目,我当时对领域模型的理解显然是错误的。我将 ORM 层视为域模型,我们希望使用 ORM 和分离的实体,并且没有任何数据映射,也没有任何 DTO。这就是当时的趋势。如今,域模型不再是 ORM,拥有适当的域模型并使用 ORM 或 Web 服务作为数据源可以解决此问题。就像许多人指出的那样,服务是它的正确位置,并且具有适当的领域模型,并且不将 JPA (ORM) 视为领域模型。
Firstly it is possible that I am asking something that has been asked and answered before but I could not get a search result back. We define transactional annotations on service layer typical spring hibernate crud is usually
Controller->Manager->Dao->Orm .
I now have a situation where I need to choose between the domain model based on client site.
Say client A is using my domain model all is good but then an other client site would give me a web service and not be using our domain model.
Which layer should I be replacing . I believe it has to be DAO which will be getting me data from web service and sending it back.i.e two separately written DAO layers and plugged in based on scenario.
I have now realized that we have been doing tight coupling (if there is such a thing or say not having loose coupling) when we put @Transactional
in Service layer. So many brains can not be wrong or are they (I doubt it).
So question is "Where should "@Transactional
" be placed Service Layer or DAO ?" and is it service layer downwards I should be replacing.
Eleven years on and still relevant . If I look back at the project somethings were obviously wrong with my understanding of Domain model back then . I was regarding ORM layer as domain model and we wanted to work with ORM and detached entities and no have any data mapping and not have any DTOs. That was the trend those days. These days Domain Model is not the ORM and having a proper Domain model and using ORM or Webservices are datasources take care of this issue. Like many pointed out yes Service is the right place for it and have proper domain model and not regard JPA (ORM) as domain model.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
理想情况下,服务层 (Manager) 代表您的业务逻辑,因此应使用
@Transactional
对其进行注释。服务层可能会调用不同的DAO来执行DB操作。让我们假设一个服务方法中有 3 个 DAO 操作的情况。如果您的第一个 DAO 操作失败,其他两个操作可能仍会通过,并且您最终将得到不一致的数据库状态。注释服务层可以帮助您避免这种情况。
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.
您将希望您的服务是事务性的。如果您的 DAO 是事务性的,并且您在每个服务中调用不同的 DAO,那么您将拥有多个事务,这不是您想要的。使服务调用具有事务性,并且这些方法内的所有 DAO 调用都将参与该方法的事务。
You are going to want your services to be transactional. If your DAOs are transactional, and you call different DAOs in each service, then you would have multiple transactions, which is not what you want. Make the service calls transactional, and all DAO calls inside those methods will participate in the transactions for the method.
我建议将 @Transactional 放在服务层方法中,因为我们可以有多个 DAO 实现。通过使用它,我们可以使我们的服务成为事务性的。 refer
最佳实践是使用通用的 BasicService 来提供共同服务。
服务是放置 @Transactional 的最佳位置,服务层应该保存逻辑上进入事务的用户交互的详细级别用例行为。通过这种方式,我们可以保持 Web 应用程序代码和业务逻辑之间的分离。
有很多 CRUD 应用程序没有任何重要的业务逻辑,对于它们来说,仅在控制器和数据访问对象之间传递内容的服务层是没有用的。在这些情况下我们可以在 Dao 上添加事务注解。
所以在实践中你可以把它们放在任何一个地方,这取决于你。
通过在您的服务中进行多个调用,您需要在服务中使用@Transactional。如果将 @Transactional 放入服务中,对服务的不同调用将在不同的事务中执行。
i will suggest to put @Transactional in Service layer methods since we can have multiple DAO implementations. by using this we can made our services will be transactional. refer
best practice is to use A generic BasicService to offer common services.
The Service is the best place for putting @Transactional, service layer should hold the detail-level use case behavior for a user interaction that would logically go in a transaction. in this way we can have maintain separation between web application code and business logic.
There are a lot of CRUD applications that don't have any significant business logic, for them having a service layer that just passes stuff through between the controllers and data access objects is not useful. In these cases we can put transaction annotation on Dao.
So in practice you can put them in either place, it's up to you.
By having multiple calls in your service you need @Transactional in service. different calls to service will execute in different transactions if you put @Transactional in service.
这是基于应用程序类型的个人选择,如果应用程序跨多个模块分层并且大多数操作基于@CRUD,那么在服务级别使用@transactional注释更有意义..引擎类型应用程序,如调度程序、作业服务器、@etl报告应用程序,其中会话和用户概念不存在,那么上下文级别的传播事务是最合适的...我们不应该通过在每个结束事务性反模式的地方放置@transactional来最终创建集群事务...无论如何,对于务实事务控制 JTA2 是最合适的答案...这又取决于天气,您可以在给定情况下使用它...
It's of a personal choice based on application types, if application is layerd across many modules and majority of operations are @CRUD based ,then having @transactional annotation at service level makes more sence.. engine type application like schedulers , job servers,@etl report apps, where sessions and user concept does not exists, then propagational transaction at context level is most suitable... we should not end up creating clusterd transactions by putting @transactional every where ending up transactional anti patters...anyways for pragmatic transaction control JTA2 is most suitable answer...again it depends on weather you can use it in a given situations...
你应该在服务层使用@Transactional,如果你想改变客户端B的域模型,你必须在不同的模型中提供相同的数据,你可以通过提供不同的服务来改变域模型而不影响DAO层或通过创建接口并在不同模型中实现该接口,并使用相同的服务填充基于客户端的模型。此决定基于业务需求和项目范围。
You should use @Transactional at service layer, if you want to change the domain model for client B where you have to provide the same data in a different model,you can change the domain model without impacting the DAO layer by providing a different service or by creating a interface and implementing the interface in different model and with the same service populate the model based on the client.This decision is based on the business requirement and the scope of the project.
仅当我们必须在多个数据库、表或存储库之间操作数据时,我们才应该使用@Transactional,例如,如果一个存储库无法插入数据,服务应该回滚事务,在这种情况下,我认为最好的做法是在服务级别添加@Transactional。
但我们永远不会在控制器级别添加@Transactional!
We should use @Transactional only if we have to manipulat data between multiple database or table or repositories, service should rollback transaction if one repository faild to insert data for exemple, in this case i think it's best practices to add @Transctional on services level.
but we wi never add @Transactional on Controller level !
在做出决定之前,另一个重要的观点是,如果服务层没有网络调用(或任何运行缓慢的任务),那么该服务可以使用@Transactional进行注释。
问:为什么这很重要?
答:答案是,当您执行数据库查询时,数据库线程将保持暂停状态,直到事务提交或回滚。因此,当执行缓慢的任务(如网络调用)时,数据库线程会不必要地处于暂停状态,从而降低整个系统的可扩展性。
问:但是系统的可扩展性如何变得较差?
答:考虑一个大规模系统,您不断需要数据库线程从数据库中提取一些数据,但如果数据库线程保持搁置,池很快就会耗尽,导致没有线程可用于其他调用来执行数据库查询。
One more perspective that is important before making a decision is if the service layer has no network calls (or any slow-running task), then the service can annotated with @Transactional.
Q: Why does this matter?
A: The answer is that when you execute a DB query, the DB thread is kept on hold until the transaction is either committed or rollbacked. So when executing a slow task (like a network call), the DB thread is on hold unnecessarily making the overall system less scalable.
Q: But how does the system become less scalable?
A: Consider a high-scale system where you continuously need a DB thread to pull in some data from DB, but if DB threads are kept on hold, the pool quickly gets exhausted making no thread available for other calls to execute DB queries.
我在编程课上听说过,dao层负责与数据库交互,而服务是一组操作,可能与dao有关,因此也可能与数据库无关,并且该组操作在一个事务中,意味着更好的服务是事务性的。
i have heard in a programming class,that dao layer is responsible for interacting with database, and service is a set of operations might be with dao and therefore database or not and that set of operation is in one transaction, mean is better service be transactional.