-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add support for transactions Co-authored-by: klinson <klinson@163.com> Co-authored-by: levon80999 <levonb@ucraft.com> * Start single-member replica set in CI Co-authored-by: levon80999 <levonb@ucraft.com> * Add connection options for faster failures in tests The faster connection and server selection timeouts ensure we don't spend too much time waiting for the inevitable as we're expecting fast connections on CI systems Co-authored-by: levon80999 <levonb@ucraft.com> * Apply readme code review suggestions * Simplify replica set creation in CI * Apply feedback from code review * Update naming of database env variable in tests * Use default argument for server selection (which defaults to primary) * Revert "Simplify replica set creation in CI" This partially reverts commit 203160e. The simplified call unfortunately breaks tests. * Pass connection instance to transactional closure This is consistent with the behaviour of the original ManagesTransactions concern. * Correctly re-throw exception when callback attempts have been exceeded. * Limit transaction lifetime to 5 seconds This ensures that hung transactions don't block any subsequent operations for an unnecessary period of time. * Add build step to print MongoDB server status * Update src/Concerns/ManagesTransactions.php Co-authored-by: Jeremy Mikola <jmikola@gmail.com> Co-authored-by: klinson <klinson@163.com> Co-authored-by: levon80999 <levonb@ucraft.com> Co-authored-by: Jeremy Mikola <jmikola@gmail.com>
- Loading branch information
1 parent
0606fc0
commit e5e9193
Showing
9 changed files
with
672 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
<?php | ||
|
||
namespace Jenssegers\Mongodb\Concerns; | ||
|
||
use Closure; | ||
use MongoDB\Client; | ||
use MongoDB\Driver\Exception\RuntimeException; | ||
use MongoDB\Driver\Session; | ||
use function MongoDB\with_transaction; | ||
use Throwable; | ||
|
||
/** | ||
* @see https://docs.mongodb.com/manual/core/transactions/ | ||
*/ | ||
trait ManagesTransactions | ||
{ | ||
protected ?Session $session = null; | ||
|
||
protected $transactions = 0; | ||
|
||
/** | ||
* @return Client | ||
*/ | ||
abstract public function getMongoClient(); | ||
|
||
public function getSession(): ?Session | ||
{ | ||
return $this->session; | ||
} | ||
|
||
private function getSessionOrCreate(): Session | ||
{ | ||
if ($this->session === null) { | ||
$this->session = $this->getMongoClient()->startSession(); | ||
} | ||
|
||
return $this->session; | ||
} | ||
|
||
private function getSessionOrThrow(): Session | ||
{ | ||
$session = $this->getSession(); | ||
|
||
if ($session === null) { | ||
throw new RuntimeException('There is no active session.'); | ||
} | ||
|
||
return $session; | ||
} | ||
|
||
/** | ||
* Starts a transaction on the active session. An active session will be created if none exists. | ||
*/ | ||
public function beginTransaction(array $options = []): void | ||
{ | ||
$this->getSessionOrCreate()->startTransaction($options); | ||
$this->transactions = 1; | ||
} | ||
|
||
/** | ||
* Commit transaction in this session. | ||
*/ | ||
public function commit(): void | ||
{ | ||
$this->getSessionOrThrow()->commitTransaction(); | ||
$this->transactions = 0; | ||
} | ||
|
||
/** | ||
* Abort transaction in this session. | ||
*/ | ||
public function rollBack($toLevel = null): void | ||
{ | ||
$this->getSessionOrThrow()->abortTransaction(); | ||
$this->transactions = 0; | ||
} | ||
|
||
/** | ||
* Static transaction function realize the with_transaction functionality provided by MongoDB. | ||
* | ||
* @param int $attempts | ||
*/ | ||
public function transaction(Closure $callback, $attempts = 1, array $options = []): mixed | ||
{ | ||
$attemptsLeft = $attempts; | ||
$callbackResult = null; | ||
$throwable = null; | ||
|
||
$callbackFunction = function (Session $session) use ($callback, &$attemptsLeft, &$callbackResult, &$throwable) { | ||
$attemptsLeft--; | ||
|
||
if ($attemptsLeft < 0) { | ||
$session->abortTransaction(); | ||
|
||
return; | ||
} | ||
|
||
// Catch, store, and re-throw any exception thrown during execution | ||
// of the callable. The last exception is re-thrown if the transaction | ||
// was aborted because the number of callback attempts has been exceeded. | ||
try { | ||
$callbackResult = $callback($this); | ||
} catch (Throwable $throwable) { | ||
throw $throwable; | ||
} | ||
}; | ||
|
||
with_transaction($this->getSessionOrCreate(), $callbackFunction, $options); | ||
|
||
if ($attemptsLeft < 0 && $throwable) { | ||
throw $throwable; | ||
} | ||
|
||
return $callbackResult; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.