diff OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp @ 4613:2684544ff03c db-changes

maximum number of database retries for writer collisions is now set by the plugins
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 08 Apr 2021 10:46:12 +0200
parents 4982733a4e39
children fda80844b920
line wrap: on
line diff
--- a/OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp	Wed Apr 07 10:41:39 2021 +0200
+++ b/OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp	Thu Apr 08 10:46:12 2021 +0200
@@ -588,6 +588,8 @@
   void StatelessDatabaseOperations::ApplyInternal(IReadOnlyOperations* readOperations,
                                                   IReadWriteOperations* writeOperations)
   {
+    boost::shared_lock<boost::shared_mutex> lock(mutex_);  // To protect "factory_" and "maxRetries_"
+
     if ((readOperations == NULL && writeOperations == NULL) ||
         (readOperations != NULL && writeOperations != NULL))
     {
@@ -599,7 +601,7 @@
       throw OrthancException(ErrorCode_BadSequenceOfCalls, "No transaction context was provided");     
     }
     
-    unsigned int count = 0;
+    unsigned int attempt = 0;
 
     for (;;)
     {
@@ -638,14 +640,16 @@
       {
         if (e.GetErrorCode() == ErrorCode_DatabaseCannotSerialize)
         {
-          if (count >= maxRetries_)
+          if (attempt >= maxRetries_)
           {
             throw;
           }
           else
           {
-            count++;
-            boost::this_thread::sleep(boost::posix_time::milliseconds(100 * count));
+            attempt++;
+
+            // The "rand()" adds some jitter to de-synchronize writers
+            boost::this_thread::sleep(boost::posix_time::milliseconds(50 * attempt + 5 * (rand() % 10)));
           }          
         }
         else
@@ -659,9 +663,9 @@
   
   StatelessDatabaseOperations::StatelessDatabaseOperations(IDatabaseWrapper& db) : 
     db_(db),
-    maxRetries_(10),
     mainDicomTagsRegistry_(new MainDicomTagsRegistry),
-    hasFlushToDisk_(db.HasFlushToDisk())
+    hasFlushToDisk_(db.HasFlushToDisk()),
+    maxRetries_(0)
   {
   }
 
@@ -681,6 +685,8 @@
 
   void StatelessDatabaseOperations::SetTransactionContextFactory(ITransactionContextFactory* factory)
   {
+    boost::unique_lock<boost::shared_mutex> lock(mutex_);
+
     if (factory == NULL)
     {
       throw OrthancException(ErrorCode_NullPointer);
@@ -696,6 +702,13 @@
   }
     
 
+  void StatelessDatabaseOperations::SetMaxDatabaseRetries(unsigned int maxRetries)
+  {
+    boost::unique_lock<boost::shared_mutex> lock(mutex_);
+    maxRetries_ = maxRetries;
+  }
+  
+
   void StatelessDatabaseOperations::Apply(IReadOnlyOperations& operations)
   {
     ApplyInternal(&operations, NULL);