다중 서비스 계층 및 데이터베이스 트랜잭션
-
06-07-2019 - |
문제
여러 서비스 계층에서 트랜잭션을 가장 잘 처리하는 방법이 궁금합니다. 서비스 계층은 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 내에서 중첩 된 거래를 시도하지 마십시오.
트랜잭션은 DB 연결에 전 세계적입니다. RDBMS가 기본적으로 중첩 거래를 지원하지 않는 한 그리고 DB API는 중첩 트랜잭션을 노출시키고 이상을 수행 할 수 있습니다.
자세한 내용은 내 답변을 참조하십시오 트랜잭션이 이미 시작된 것을 어떻게 감지합니까?
PHP를 사용하고 있으므로 거래 범위는 최대 단일 요청입니다. 따라서 서비스 계층 Transa가 아닌 컨테이너 관리 트랜잭션을 사용해야합니다. 즉, 요청 처리가 시작될 때 트랜잭션을 시작하고 요청 처리를 마치면 커밋 (또는 롤백)을 시작하십시오.
롤백이 필요한 예외가 중첩 된 ORM 액션 내에서 깊은 곳에서 발생하는 경우 예외를 사용하여 기포를하고 컨테이너 (예 : PHP 액션 컨트롤러)를 처리하십시오.
다른 팁
거래의 집계에 직면하고 있습니까? 이 의사 코드는 내가 당신이 말하는 것과 일치합니까?
try
begin application transaction
begin ORM transaction 1
create new user
commit request
begin ORM transaction 2
create new client
commit request
begin ORM transaction 3
create user client association
commit request
commit application tx
catch()
abort ORM tx 3
abort ORM tx 2
abort ORM tx 1
abort app tx
언제든 중첩 된 거래의 롤백은 예외를 던질 수 있으며 이러한 예외는 모든 중첩 트랜잭션을 논리적으로 롤백합니다. 2 단계 커밋.
나는 당신이 tho 후에 당신을 얻지 못할 수도 있습니다.