40
40
41
41
namespace OC \Files \Cache ;
42
42
43
+ use Doctrine \DBAL \Exception \RetryableException ;
43
44
use Doctrine \DBAL \Exception \UniqueConstraintViolationException ;
44
45
use OC \Files \Search \SearchComparison ;
45
46
use OC \Files \Search \SearchQuery ;
@@ -692,7 +693,6 @@ public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
692
693
throw new \Exception ('Invalid target storage id: ' . $ targetStorageId );
693
694
}
694
695
695
- $ this ->connection ->beginTransaction ();
696
696
if ($ sourceData ['mimetype ' ] === 'httpd/unix-directory ' ) {
697
697
//update all child entries
698
698
$ sourceLength = mb_strlen ($ sourcePath );
@@ -715,11 +715,25 @@ public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
715
715
$ query ->set ('encrypted ' , $ query ->createNamedParameter (0 , IQueryBuilder::PARAM_INT ));
716
716
}
717
717
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 , 4 ] 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 4 times.
729
+ if ($ i === 4 ) {
730
+ throw $ e ;
731
+ }
732
+
733
+ // Sleep for 1 seconde to give some time to the other transaction to finish.
734
+ sleep (1 );
735
+ $ this ->connection ->rollBack ();
736
+ }
723
737
}
724
738
}
725
739
0 commit comments