comparison MySQL/Plugins/MySQLStorageArea.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
21 21
22 #include "MySQLStorageArea.h" 22 #include "MySQLStorageArea.h"
23 23
24 #include "../../Framework/MySQL/MySQLDatabase.h" 24 #include "../../Framework/MySQL/MySQLDatabase.h"
25 #include "../../Framework/MySQL/MySQLTransaction.h" 25 #include "../../Framework/MySQL/MySQLTransaction.h"
26 #include "MySQLDefinitions.h"
26 27
27 #include <Core/Logging.h> 28 #include <Core/Logging.h>
28 29
29 #include <boost/math/special_functions/round.hpp> 30 #include <boost/math/special_functions/round.hpp>
30 31
35 { 36 {
36 std::auto_ptr<MySQLDatabase> db(new MySQLDatabase(parameters_)); 37 std::auto_ptr<MySQLDatabase> db(new MySQLDatabase(parameters_));
37 38
38 db->Open(); 39 db->Open();
39 40
40 if (parameters_.HasLock())
41 { 41 {
42 db->AdvisoryLock(43 /* some arbitrary constant */); 42 MySQLDatabase::TransientAdvisoryLock lock(*db, MYSQL_LOCK_DATABASE_SETUP);
43 }
44
45 /**
46 * Try and acquire a transient advisory lock to protect the setup
47 * of the database, because concurrent statements like "CREATE
48 * TABLE" are not protected by transactions.
49 * https://groups.google.com/d/msg/orthanc-users/yV3LSTh_TjI/h3PRApJFBAAJ
50 **/
51 MySQLDatabase::TransientAdvisoryLock lock(*db, 44 /* some arbitrary constant */);
52
53 {
54 MySQLTransaction t(*db); 43 MySQLTransaction t(*db);
55 44
56 int64_t size; 45 int64_t size;
57 if (db->LookupGlobalIntegerVariable(size, "max_allowed_packet")) 46 if (db->LookupGlobalIntegerVariable(size, "max_allowed_packet"))
58 { 47 {
80 "type INTEGER NOT NULL)", false); 69 "type INTEGER NOT NULL)", false);
81 70
82 t.Commit(); 71 t.Commit();
83 } 72 }
84 73
74 /**
75 * WARNING: This lock must be acquired after
76 * "MYSQL_LOCK_DATABASE_SETUP" is released. Indeed, in MySQL <
77 * 5.7, it is impossible to acquire more than one lock at a time,
78 * as calling "SELECT GET_LOCK()" releases all the
79 * previously-acquired locks.
80 * https://dev.mysql.com/doc/refman/5.7/en/locking-functions.html
81 **/
82 if (parameters_.HasLock())
83 {
84 db->AdvisoryLock(MYSQL_LOCK_STORAGE);
85 }
86
85 return db.release(); 87 return db.release();
86 } 88 }
87 89
88 90
89 MySQLStorageArea::MySQLStorageArea(const MySQLParameters& parameters) : 91 MySQLStorageArea::MySQLStorageArea(const MySQLParameters& parameters) :