Skip to content

Commit 4ad52b0

Browse files
author
Mesut Aydın
committed
ManageTransactions compatible with Illuminate\DB
1 parent 94d4fb2 commit 4ad52b0

File tree

1 file changed

+41
-25
lines changed

1 file changed

+41
-25
lines changed

src/Concerns/ManagesTransactions.php

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -78,41 +78,57 @@ public function rollBack($toLevel = null): void
7878
}
7979

8080
/**
81-
* Static transaction function realize the with_transaction functionality provided by MongoDB.
82-
*
83-
* @param int $attempts
81+
* @param Closure $callback
82+
* @param $attempts
83+
* @param Closure|null $onFailure
84+
* @return mixed
85+
* @throws Throwable
8486
*/
85-
public function transaction(Closure $callback, $attempts = 1, array $options = []): mixed
87+
public function transaction(Closure $callback, $attempts = 1, ?Closure $onFailure = null): mixed
8688
{
87-
$attemptsLeft = $attempts;
88-
$callbackResult = null;
89-
$throwable = null;
9089

91-
$callbackFunction = function (Session $session) use ($callback, &$attemptsLeft, &$callbackResult, &$throwable) {
92-
$attemptsLeft--;
90+
if ($attempts <= 0) {
91+
throw new \InvalidArgumentException('Attempts must be at least 1');
92+
}
9393

94-
if ($attemptsLeft < 0) {
95-
$session->abortTransaction();
94+
$attemptsLeft = $attempts;
95+
$lastException = null;
9696

97-
return;
98-
}
97+
while ($attemptsLeft--) {
98+
$this->session = $this->getMongoClient()->startSession();
9999

100-
// Catch, store, and re-throw any exception thrown during execution
101-
// of the callable. The last exception is re-thrown if the transaction
102-
// was aborted because the number of callback attempts has been exceeded.
103100
try {
104-
$callbackResult = $callback($this);
105-
} catch (Throwable $throwable) {
106-
throw $throwable;
101+
$this->session->startTransaction();
102+
$result = $callback();
103+
$this->session->commitTransaction();
104+
105+
return $result;
106+
} catch (\Throwable $e) {
107+
if ($this->session->isInTransaction()) {
108+
$this->session->abortTransaction();
109+
}
110+
111+
$lastException = $e;
112+
113+
if ($e instanceof RuntimeException && $attemptsLeft > 0) {
114+
continue;
115+
}
116+
117+
if ($onFailure) {
118+
return $onFailure($e);
119+
}
120+
121+
throw $e;
122+
} finally {
123+
$this->session->endSession();
124+
$this->session = null;
107125
}
108-
};
109-
110-
with_transaction($this->getSessionOrCreate(), $callbackFunction, $options);
126+
}
111127

112-
if ($attemptsLeft < 0 && $throwable) {
113-
throw $throwable;
128+
if ($onFailure) {
129+
return $onFailure($lastException);
114130
}
115131

116-
return $callbackResult;
132+
throw $lastException;
117133
}
118134
}

0 commit comments

Comments
 (0)