comparison MySQL/Plugins/MySQLIndex.cpp @ 137:52b3859ee0b7

MySQL: acquiring named locks instead of numbers
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 09 May 2019 11:29:17 +0200
parents e26690365c25
children 4cd7e45b671e
comparison
equal deleted inserted replaced
136:3266785d5627 137:52b3859ee0b7
22 #include "MySQLIndex.h" 22 #include "MySQLIndex.h"
23 23
24 #include "../../Framework/Plugins/GlobalProperties.h" 24 #include "../../Framework/Plugins/GlobalProperties.h"
25 #include "../../Framework/MySQL/MySQLDatabase.h" 25 #include "../../Framework/MySQL/MySQLDatabase.h"
26 #include "../../Framework/MySQL/MySQLTransaction.h" 26 #include "../../Framework/MySQL/MySQLTransaction.h"
27 #include "MySQLDefinitions.h"
27 28
28 #include <EmbeddedResources.h> // Auto-generated file 29 #include <EmbeddedResources.h> // Auto-generated file
29 30
30 #include <Core/Logging.h> 31 #include <Core/Logging.h>
31 #include <Core/OrthancException.h> 32 #include <Core/OrthancException.h>
67 } 68 }
68 69
69 std::auto_ptr<MySQLDatabase> db(new MySQLDatabase(parameters_)); 70 std::auto_ptr<MySQLDatabase> db(new MySQLDatabase(parameters_));
70 71
71 db->Open(); 72 db->Open();
72
73 db->Execute("SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE", false); 73 db->Execute("SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE", false);
74 74
75 if (parameters_.HasLock()) 75 {
76 { 76 MySQLDatabase::TransientAdvisoryLock lock(*db, MYSQL_LOCK_DATABASE_SETUP);
77 db->AdvisoryLock(42 /* some arbitrary constant */);
78 }
79
80 /**
81 * Try and acquire a transient advisory lock to protect the setup
82 * of the database, because concurrent statements like "CREATE
83 * TABLE" are not protected by transactions.
84 * https://groups.google.com/d/msg/orthanc-users/yV3LSTh_TjI/h3PRApJFBAAJ
85 **/
86 MySQLDatabase::TransientAdvisoryLock lock(*db, 44 /* some arbitrary constant */);
87
88 {
89 MySQLTransaction t(*db); 77 MySQLTransaction t(*db);
90 78
91 db->Execute("ALTER DATABASE " + parameters_.GetDatabase() + 79 db->Execute("ALTER DATABASE " + parameters_.GetDatabase() +
92 " CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci", false); 80 " CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci", false);
93 81
180 LOG(ERROR) << "MySQL plugin is incompatible with database schema revision: " << revision; 168 LOG(ERROR) << "MySQL plugin is incompatible with database schema revision: " << revision;
181 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); 169 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database);
182 } 170 }
183 171
184 t.Commit(); 172 t.Commit();
173 }
174
175 /**
176 * WARNING: This lock must be acquired after
177 * "MYSQL_LOCK_DATABASE_SETUP" is released. Indeed, in MySQL <
178 * 5.7, it is impossible to acquire more than one lock at a time,
179 * as calling "SELECT GET_LOCK()" releases all the
180 * previously-acquired locks.
181 * https://dev.mysql.com/doc/refman/5.7/en/locking-functions.html
182 **/
183 if (parameters_.HasLock())
184 {
185 db->AdvisoryLock(MYSQL_LOCK_INDEX);
185 } 186 }
186 187
187 return db.release(); 188 return db.release();
188 } 189 }
189 190