query($table); } /** * Get the current transaction, if there is one. * @return Transaction|null */ public function getCurrentTransaction(): ?Transaction { return $this->transaction; } /** * Called when the state of a transaction changed (inactive -> active or active -> inactive). * @param Transaction $transaction * @return void * @throws NotCurrentTransactionException */ public function onTransactionStateChanged(Transaction $transaction): void { if ($transaction->isActive()) { // Set the newly active transaction as the current one. // Its parent should be the current transaction, if it exists. if (!empty($transaction->getParent()) && $transaction->getParent()->getUuid() != $this->transaction->getUuid()) throw new NotCurrentTransactionException($this->transaction, $transaction->getParent()); $this->transaction = $transaction; } else { // The transaction has been terminated, it should be the current one. if (!empty($this->transaction) && $this->transaction->getUuid() != $transaction->getUuid()) throw new NotCurrentTransactionException($this->transaction, $transaction); $this->transaction = $transaction->getParent(); } } /** * Start a new transaction (in the current one, if there is one). * @return Transaction The new transaction. * @throws NotCurrentTransactionException */ public function startTransaction(): Transaction { // Create the transaction as a child of the existing one, if there is one. $newTransaction = new Transaction($this, $this->transaction); if (!empty($this->transaction)) // Set the new transaction as child of the current one. $this->transaction->setChild($newTransaction); $newTransaction->start(); // Start the new transaction. return $newTransaction; // Return the new transaction. } /** * Start a new transaction and execute the function in parameter. * The transaction will be committed / rolled back automatically at the end of the function. * A rollback happen if any exception is thrown in the function. * @param callable(Transaction): mixed $function The function to execute in a transaction. * @return mixed Function result. * @throws Throwable */ public function transaction(callable $function): mixed { // Start a new transaction. $transaction = $this->startTransaction(); try { // Trying to run the function in the started transaction. $result = $function($transaction); // The function finished successfully, commit the transaction. $transaction->commit(); // Return result of the function. return $result; } catch (Throwable $throwable) { // An exception has been thrown, rolling back the transaction and throw it again. $transaction->rollback(); throw $throwable; } } }