多服务层和数据库事务 [英] Multiple Service Layers and Database Transactions

查看:171
本文介绍了多服务层和数据库事务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是想知道如何最好地处理跨多个服务层的事务。服务层使用ORM存储和从数据库检索。应该在各个服务层内知道并处理交易吗?或者应该由另一个层处理?



例如:我为用户和客户端提供了两个服务层。我想:



1)创建并保存新客户

2)创建并保存新用户

3)将该用户分配给客户



一个简单的示例可能类似于这:

  $ userManagementService = new UserManagementService; 
$ newUserData = array(...);
$ newUser = $ userManagementService-> create($ newUserData);

$ clientManagementService = new ClientManagementService;
$ newClientData = array(...);
$ newClient = $ clientManagementService-> create($ newClientData);

$ userManagementService-> assignUserToClient($ newUser,$ newClient);



事务逻辑应该放在哪里?

解决方案

不要尝试在服务层或ORM内执行嵌套事务。



事务是数据库连接的全局事务。除非您的RDBMS本身支持嵌套事务,您的数据库API暴露嵌套事务,您可能会遇到异常。



有关详细信息, 如何检测该事务是否已启动?



由于您使用的是PHP,您的交易范围最多只有一个请求。所以你应该使用容器管理的事务,而不是服务层transa。也就是说,在处理请求开始时启动事务,并在处理请求时提交(或回滚)。



如果需要回滚的异常发生在嵌套ORM操作中,那么使用异常来冒泡它,并让容器(即你的PHP动作控制器)


I'm just wondering how to best handle transactions across multiple service layers. The service layers use an ORM to store and retrieve from the database. Should the transactions be known and handled within the individual service layers? Or should they be handled by another layer?

For example: I have two service layers for users and clients. I would like to:

1) Create and save a new client
2) Create and save a new user
3) Assign that user to the client

All within a single transaction.

A simple example might look like this:

$userManagementService = new UserManagementService;
$newUserData = array(...);
$newUser = $userManagementService->create($newUserData);

$clientManagementService = new ClientManagementService;
$newClientData = array(...);
$newClient = $clientManagementService->create($newClientData);

$userManagementService->assignUserToClient($newUser, $newClient);

Where should transaction logic go?

解决方案

Do not try to do nested transactions within service layers or within the ORM.

Transactions are global to the DB connection. Unless your RDBMS supports nested transactions natively and your DB API exposes nested transactions, you can run into anomalies.

For details, see my answer to How do detect that transaction has already been started?

Since you're using PHP, the scope of your transactions is at most a single request. So you should just use container-managed transactions, not service-layer transa. That is, start the transaction at the start of handling the request, and commit (or rollback) as you finish handling the request.

If an exception requiring a rollback occurs deep within nested ORM actions, then bubble that up by using an Exception, and let the container (i.e. your PHP action controller) take care of it.

这篇关于多服务层和数据库事务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆