Mercurial > hg > orthanc-databases
comparison Framework/MySQL/MySQLDatabase.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 |
---|---|
288 return false; | 288 return false; |
289 } | 289 } |
290 } | 290 } |
291 | 291 |
292 | 292 |
293 bool MySQLDatabase::RunAdvisoryLockStatement(const std::string& s) | 293 bool MySQLDatabase::RunAdvisoryLockStatement(Query& query, |
294 { | 294 const std::string& lock) |
295 Query query(s, false); | 295 { |
296 const std::string& dbName = parameters_.GetDatabase(); | |
297 | |
298 // Prepend the name of the lock by the database name. This allows | |
299 // to create a namespace for advisory locks: | |
300 // https://groups.google.com/d/msg/orthanc-users/yV3LSTh_TjI/MQIcvnMlAQAJ | |
301 std::string prefix; | |
302 prefix.reserve(dbName.size()); | |
303 for (size_t i = 0; i < dbName.size(); i++) | |
304 { | |
305 if (isalnum(dbName[i]) || | |
306 dbName[i] == '$' || | |
307 dbName[i] == '_') | |
308 { | |
309 prefix.push_back(dbName[i]); | |
310 } | |
311 } | |
312 | |
313 query.SetType("lock", ValueType_Utf8String); | |
314 | |
296 MySQLStatement statement(*this, query); | 315 MySQLStatement statement(*this, query); |
297 | 316 |
298 MySQLTransaction t(*this); | |
299 Dictionary args; | 317 Dictionary args; |
300 | 318 args.SetUtf8Value("lock", prefix + "." + lock); |
301 std::auto_ptr<IResult> result(t.Execute(statement, args)); | 319 |
302 | 320 bool success; |
303 bool success = (!result->IsDone() && | 321 |
304 result->GetField(0).GetType() == ValueType_Integer64 && | 322 { |
305 dynamic_cast<const Integer64Value&>(result->GetField(0)).GetValue() == 1); | 323 MySQLTransaction t(*this); |
306 | 324 std::auto_ptr<IResult> result(t.Execute(statement, args)); |
307 t.Commit(); | 325 |
326 success = (!result->IsDone() && | |
327 result->GetField(0).GetType() == ValueType_Integer64 && | |
328 dynamic_cast<const Integer64Value&>(result->GetField(0)).GetValue() == 1); | |
329 | |
330 t.Commit(); | |
331 } | |
308 | 332 |
309 return success; | 333 return success; |
310 } | 334 } |
311 | 335 |
312 | 336 |
313 bool MySQLDatabase::AcquireAdvisoryLock(int32_t lock) | 337 bool MySQLDatabase::AcquireAdvisoryLock(const std::string& lock) |
314 { | 338 { |
315 return RunAdvisoryLockStatement("SELECT GET_LOCK('Lock" + | 339 Query query("SELECT GET_LOCK(${lock}, 0)", false); |
316 boost::lexical_cast<std::string>(lock) + "', 0);"); | 340 return RunAdvisoryLockStatement(query, lock); |
317 } | 341 } |
318 | 342 |
319 | 343 |
320 bool MySQLDatabase::ReleaseAdvisoryLock(int32_t lock) | 344 bool MySQLDatabase::ReleaseAdvisoryLock(const std::string& lock) |
321 { | 345 { |
322 return RunAdvisoryLockStatement("SELECT RELEASE_LOCK('Lock" + | 346 Query query("SELECT RELEASE_LOCK(${lock})", false); |
323 boost::lexical_cast<std::string>(lock) + "');"); | 347 return RunAdvisoryLockStatement(query, lock); |
324 } | 348 } |
325 | 349 |
326 | 350 |
327 void MySQLDatabase::AdvisoryLock(int32_t lock) | 351 void MySQLDatabase::AdvisoryLock(const std::string& lock) |
328 { | 352 { |
329 if (!AcquireAdvisoryLock(lock)) | 353 if (!AcquireAdvisoryLock(lock)) |
330 { | 354 { |
331 LOG(ERROR) << "The MySQL database is locked by another instance of Orthanc"; | 355 LOG(ERROR) << "The MySQL database is locked by another instance of Orthanc"; |
332 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); | 356 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); |
511 } | 535 } |
512 | 536 |
513 | 537 |
514 MySQLDatabase::TransientAdvisoryLock:: | 538 MySQLDatabase::TransientAdvisoryLock:: |
515 TransientAdvisoryLock(MySQLDatabase& database, | 539 TransientAdvisoryLock(MySQLDatabase& database, |
516 int32_t lock) : | 540 const std::string& lock) : |
517 database_(database), | 541 database_(database), |
518 lock_(lock) | 542 lock_(lock) |
519 { | 543 { |
520 bool locked = true; | 544 bool locked = true; |
521 | 545 |