Skip to content

Commit 560e934

Browse files
committed
Move retry logic to the QueryBuilder
Signed-off-by: Louis Chemineau <louis@chmn.me>
1 parent ff2100a commit 560e934

3 files changed

Lines changed: 38 additions & 24 deletions

File tree

lib/private/DB/QueryBuilder/QueryBuilder.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
*/
3131
namespace OC\DB\QueryBuilder;
3232

33+
use Doctrine\DBAL\Exception\RetryableException;
3334
use Doctrine\DBAL\Platforms\MySQLPlatform;
3435
use Doctrine\DBAL\Platforms\OraclePlatform;
3536
use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
@@ -76,6 +77,8 @@ class QueryBuilder implements IQueryBuilder {
7677
/** @var string */
7778
protected $lastInsertedTable;
7879

80+
private $retryLimit = 4;
81+
7982
/**
8083
* Initializes a new QueryBuilder.
8184
*
@@ -277,13 +280,34 @@ public function execute() {
277280
]);
278281
}
279282

280-
$result = $this->queryBuilder->execute();
283+
for ($i = 1; $i <= $this->retryLimit; $i++) {
284+
try {
285+
$result = $this->queryBuilder->execute();
286+
break;
287+
} catch (RetryableException $e) {
288+
// Throw if we reached retryLimit.
289+
if ($i === $this->retryLimit) {
290+
throw $e;
291+
}
292+
293+
// Sleep a bit to give some time to the other transaction to finish.
294+
usleep(100 * 1000 * $i);
295+
}
296+
}
297+
281298
if (is_int($result)) {
282299
return $result;
283300
}
284301
return new ResultAdapter($result);
285302
}
286303

304+
/**
305+
* @param int $retryLimit - Retry the query up to $retryLimit times in case of a RetryableException. Initially equal to 4.
306+
*/
307+
public function setRetryLimit(int $retryLimit): void {
308+
$this->retryLimit = $retryLimit;
309+
}
310+
287311
public function executeQuery(): IResult {
288312
if ($this->getType() !== \Doctrine\DBAL\Query\QueryBuilder::SELECT) {
289313
throw new \RuntimeException('Invalid query type, expected SELECT query');

lib/private/Files/Cache/Cache.php

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040

4141
namespace OC\Files\Cache;
4242

43-
use Doctrine\DBAL\Exception\RetryableException;
4443
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
4544
use OC\Files\Search\SearchComparison;
4645
use OC\Files\Search\SearchQuery;
@@ -715,28 +714,12 @@ public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
715714
$query->set('encrypted', $query->createNamedParameter(0, IQueryBuilder::PARAM_INT));
716715
}
717716

718-
// Retry transaction in case of RetryableException like deadlocks.
719-
// Retry up to 4 times because we should receive up to 4 concurrent requests from the frontend
720-
$retryLimit = 4;
721-
for ($i = 1; $i <= $retryLimit; $i++) {
722-
try {
723-
$this->connection->beginTransaction();
724-
$query->executeStatement();
725-
break;
726-
} catch (\OC\DatabaseException $e) {
727-
$this->connection->rollBack();
728-
throw $e;
729-
} catch (RetryableException $e) {
730-
// Simply throw if we already retried 4 times.
731-
if ($i === $retryLimit) {
732-
throw $e;
733-
}
734-
735-
$this->connection->rollBack();
736-
737-
// Sleep a bit to give some time to the other transaction to finish.
738-
usleep(100 * 1000 * $i);
739-
}
717+
try {
718+
$this->connection->beginTransaction();
719+
$query->executeStatement(4);
720+
} catch (\OC\DatabaseException $e) {
721+
$this->connection->rollBack();
722+
throw $e;
740723
}
741724
} else {
742725
$this->connection->beginTransaction();

lib/public/DB/QueryBuilder/IQueryBuilder.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,13 @@ public function execute();
184184
*/
185185
public function executeQuery(): IResult;
186186

187+
/**
188+
* @since 30.0.0
189+
*
190+
* @param int $retryLimit - Retry the query up to $retryLimit times in case of a RetryableException. Initially equal to 4.
191+
*/
192+
public function setRetryLimit(int $retryLimit): void;
193+
187194
/**
188195
* Execute insert, update and delete statements
189196
*

0 commit comments

Comments
 (0)