Mercurial > hg > orthanc-databases
comparison PostgreSQL/Plugins/PostgreSQLIndex.cpp @ 418:a7f0f27fe33c pg-transactions
wip: advisory lock around CreateInstance: not ok see WO-139
author | Alain Mazy <am@osimis.io> |
---|---|
date | Tue, 27 Jun 2023 15:17:39 +0200 |
parents | 91124cc8a8c7 |
children | 3cdea26ece73 |
comparison
equal
deleted
inserted
replaced
417:15bfd9a76f8d | 418:a7f0f27fe33c |
---|---|
131 { | 131 { |
132 revision = 1; | 132 revision = 1; |
133 SetGlobalIntegerProperty(manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel, revision); | 133 SetGlobalIntegerProperty(manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel, revision); |
134 } | 134 } |
135 | 135 |
136 if (revision != 1) | 136 if (revision == 1) |
137 { | |
138 LOG(WARNING) << "PostgreSQL plugin: adding UNIQUE(publicId) constraint to the 'Resources' table "; | |
139 t.GetDatabaseTransaction().ExecuteMultiLines("ALTER TABLE Resources ADD UNIQUE (publicId);"); | |
140 | |
141 revision = 2; | |
142 SetGlobalIntegerProperty(manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel, revision); | |
143 } | |
144 | |
145 if (revision != 2) | |
137 { | 146 { |
138 LOG(ERROR) << "PostgreSQL plugin is incompatible with database schema revision: " << revision; | 147 LOG(ERROR) << "PostgreSQL plugin is incompatible with database schema revision: " << revision; |
139 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); | 148 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); |
140 } | 149 } |
141 | 150 |
404 Dictionary args; | 413 Dictionary args; |
405 args.SetUtf8Value("patient", hashPatient); | 414 args.SetUtf8Value("patient", hashPatient); |
406 args.SetUtf8Value("study", hashStudy); | 415 args.SetUtf8Value("study", hashStudy); |
407 args.SetUtf8Value("series", hashSeries); | 416 args.SetUtf8Value("series", hashSeries); |
408 args.SetUtf8Value("instance", hashInstance); | 417 args.SetUtf8Value("instance", hashInstance); |
409 | 418 |
410 statement.Execute(args); | 419 { // The CreateInstance procedure is not 100% safe in highly concurrent environments when the |
420 // transaction isolation is set to "READ COMMITED": (e.g, with 10 clients | |
421 // anonymizing studies in parallel with the "ResourceModification" config set to 8, we have observed | |
422 // the same series being created twice). Therefore, we protect the whole CreateInstance procedure | |
423 // with an advisory lock | |
424 PostgreSQLDatabase& db = dynamic_cast<PostgreSQLDatabase&>(manager.GetDatabase()); | |
425 PostgreSQLDatabase::TransientAdvisoryLock lock(db, POSTGRESQL_LOCK_CREATE_INSTANCE, 100, 1); | |
426 | |
427 statement.Execute(args); | |
428 } | |
411 | 429 |
412 if (statement.IsDone() || | 430 if (statement.IsDone() || |
413 statement.GetResultFieldsCount() != 8) | 431 statement.GetResultFieldsCount() != 8) |
414 { | 432 { |
415 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); | 433 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); |