Domanda

Mi sto solo chiedendo come gestire al meglio le transazioni su più livelli di servizio. I livelli di servizio utilizzano un ORM per archiviare e recuperare dal database. Le transazioni devono essere conosciute e gestite all'interno dei singoli livelli di servizio? O dovrebbero essere gestiti da un altro livello?

Ad esempio: ho due livelli di servizio per utenti e client. Vorrei:

1) Crea e salva un nuovo client
2) Crea e salva un nuovo utente
3) Assegnare tale utente al client

Tutto in un'unica transazione.

Un semplice esempio potrebbe apparire così:

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

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

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

Dove dovrebbe andare la logica delle transazioni?

È stato utile?

Soluzione

Non tentare di eseguire transazioni nidificate all'interno dei livelli di servizio o all'interno dell'ORM.

Le transazioni sono globali alla connessione DB. A meno che RDBMS non supporti le transazioni nidificate in modo nativo e l'API DB espone transazioni nidificate, è possibile riscontrare anomalie.

Per i dettagli, vedere la mia risposta a Come rilevare che la transazione è già stata avviata?

Dato che stai usando PHP, l'ambito delle tue transazioni è al massimo una singola richiesta. Quindi dovresti usare solo le transazioni gestite dal contenitore, non il livello di servizio transa. Cioè, avvia la transazione all'inizio della gestione della richiesta e esegui il commit (o il rollback) al termine della gestione della richiesta.

Se si verifica un'eccezione che richiede un rollback all'interno delle azioni ORM nidificate, creane una bolla usando un'eccezione e lascia che il contenitore (ovvero il tuo controller di azioni PHP) si occupi di essa.

Altri suggerimenti

Stai affrontando un'aggregazione di transazioni? Questo pseudo codice corrisponde a quello che penso tu stia dicendo?

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

In qualsiasi momento il rollback di una transazione nidificata genererà probabilmente un'eccezione e tali eccezioni porterebbero logicamente al rollback di tutte le transazioni nidificate in commit in due fasi .

Potrei non avere quello che cerchi dopo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top