Skip to content

Commit f9cc3f7

Browse files
committed
feat(files)): Add retry logic to cover deadlock situations when moving many files
Signed-off-by: Louis Chemineau <[email protected]>
1 parent 9afcec7 commit f9cc3f7

File tree

1 file changed

+18
-6
lines changed

1 file changed

+18
-6
lines changed

lib/private/Files/Cache/Cache.php

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

4141
namespace OC\Files\Cache;
4242

43+
use Doctrine\DBAL\Exception\RetryableException;
4344
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
4445
use OC\Files\Search\SearchComparison;
4546
use OC\Files\Search\SearchQuery;
@@ -692,7 +693,6 @@ public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
692693
throw new \Exception('Invalid target storage id: ' . $targetStorageId);
693694
}
694695

695-
$this->connection->beginTransaction();
696696
if ($sourceData['mimetype'] === 'httpd/unix-directory') {
697697
//update all child entries
698698
$sourceLength = mb_strlen($sourcePath);
@@ -715,11 +715,23 @@ public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
715715
$query->set('encrypted', $query->createNamedParameter(0, IQueryBuilder::PARAM_INT));
716716
}
717717

718-
try {
719-
$query->execute();
720-
} catch (\OC\DatabaseException $e) {
721-
$this->connection->rollBack();
722-
throw $e;
718+
// Retry transaction in case of RetryableException like deadlocks.
719+
foreach ([1, 2, 3] as $i) {
720+
try {
721+
$this->connection->beginTransaction();
722+
$query->execute();
723+
break;
724+
} catch (\OC\DatabaseException $e) {
725+
$this->connection->rollBack();
726+
throw $e;
727+
} catch (RetryableException $e) {
728+
// Simply throw if we already retried 3 times.
729+
if ($i === 3) {
730+
throw $e;
731+
}
732+
733+
$this->connection->rollBack();
734+
}
723735
}
724736
}
725737

0 commit comments

Comments
 (0)