Skip to content

Commit 87fb55e

Browse files
authored
Merge pull request #677 from utopia-php/with-transaction
With transactions optimization
2 parents 8a536fe + 18a2875 commit 87fb55e

File tree

2 files changed

+33
-19
lines changed

2 files changed

+33
-19
lines changed

src/Database/Adapter.php

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44

55
use Exception;
66
use Utopia\Database\Exception as DatabaseException;
7+
use Utopia\Database\Exception\Authorization as AuthorizationException;
8+
use Utopia\Database\Exception\Conflict as ConflictException;
79
use Utopia\Database\Exception\Duplicate as DuplicateException;
10+
use Utopia\Database\Exception\Limit as LimitException;
11+
use Utopia\Database\Exception\Relationship as RelationshipException;
12+
use Utopia\Database\Exception\Restricted as RestrictedException;
813
use Utopia\Database\Exception\Timeout as TimeoutException;
914
use Utopia\Database\Exception\Transaction as TransactionException;
1015

@@ -371,7 +376,10 @@ public function inTransaction(): bool
371376
*/
372377
public function withTransaction(callable $callback): mixed
373378
{
374-
for ($attempts = 0; $attempts < 3; $attempts++) {
379+
$sleep = 50_000; // 50 milliseconds
380+
$retries = 2;
381+
382+
for ($attempts = 0; $attempts <= $retries; $attempts++) {
375383
try {
376384
$this->startTransaction();
377385
$result = $callback();
@@ -380,18 +388,31 @@ public function withTransaction(callable $callback): mixed
380388
} catch (\Throwable $action) {
381389
try {
382390
$this->rollbackTransaction();
391+
392+
if (
393+
$action instanceof DuplicateException ||
394+
$action instanceof RestrictedException ||
395+
$action instanceof AuthorizationException ||
396+
$action instanceof RelationshipException ||
397+
$action instanceof ConflictException ||
398+
$action instanceof LimitException
399+
) {
400+
$this->inTransaction = 0;
401+
throw $action;
402+
}
403+
383404
} catch (\Throwable $rollback) {
384-
if ($attempts < 2) {
385-
\usleep(5000); // 5ms
405+
if ($attempts < $retries) {
406+
\usleep($sleep * ($attempts + 1));
386407
continue;
387408
}
388409

389410
$this->inTransaction = 0;
390411
throw $rollback;
391412
}
392413

393-
if ($attempts < 2) {
394-
\usleep(5000); // 5ms
414+
if ($attempts < $retries) {
415+
\usleep($sleep * ($attempts + 1));
395416
continue;
396417
}
397418

src/Database/Adapter/SQL.php

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
use Utopia\Database\Exception\NotFound as NotFoundException;
1414
use Utopia\Database\Exception\Transaction as TransactionException;
1515
use Utopia\Database\Query;
16-
use Utopia\Database\Validator\Spatial;
1716

1817
abstract class SQL extends Adapter
1918
{
@@ -66,19 +65,17 @@ public function startTransaction(): bool
6665
$this->getPDO()->prepare('ROLLBACK')->execute();
6766
}
6867

69-
$result = $this->getPDO()->beginTransaction();
68+
$this->getPDO()->beginTransaction();
69+
7070
} else {
71-
$result = $this->getPDO()->exec('SAVEPOINT transaction' . $this->inTransaction);
71+
$this->getPDO()->exec('SAVEPOINT transaction' . $this->inTransaction);
7272
}
7373
} catch (PDOException $e) {
7474
throw new TransactionException('Failed to start transaction: ' . $e->getMessage(), $e->getCode(), $e);
7575
}
7676

77-
if (!$result) {
78-
throw new TransactionException('Failed to start transaction');
79-
}
80-
8177
$this->inTransaction++;
78+
8279
return true;
8380
}
8481

@@ -124,21 +121,17 @@ public function rollbackTransaction(): bool
124121

125122
try {
126123
if ($this->inTransaction > 1) {
127-
$result = $this->getPDO()->exec('ROLLBACK TO transaction' . ($this->inTransaction - 1));
124+
$this->getPDO()->exec('ROLLBACK TO transaction' . ($this->inTransaction - 1));
128125
$this->inTransaction--;
129126
} else {
130-
$result = $this->getPDO()->rollBack();
127+
$this->getPDO()->rollBack();
131128
$this->inTransaction = 0;
132129
}
133130
} catch (PDOException $e) {
134131
throw new DatabaseException('Failed to rollback transaction: ' . $e->getMessage(), $e->getCode(), $e);
135132
}
136133

137-
if (!$result) {
138-
throw new TransactionException('Failed to rollback transaction');
139-
}
140-
141-
return $result;
134+
return true;
142135
}
143136

144137
/**

0 commit comments

Comments
 (0)