# HG changeset patch # User Sebastien Jodogne # Date 1615215896 -3600 # Node ID 648defffc8cc32f0d7821bd17429129a57dd7982 # Parent 19ea4ecd6d9a514c9d319da817bf312f6e84f398 new enum: TransactionType diff -r 19ea4ecd6d9a -r 648defffc8cc OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp --- a/OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp Mon Mar 08 15:13:25 2021 +0100 +++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp Mon Mar 08 16:04:56 2021 +0100 @@ -889,8 +889,10 @@ } - IDatabaseWrapper::ITransaction* OrthancPluginDatabase::StartTransaction() + IDatabaseWrapper::ITransaction* OrthancPluginDatabase::StartTransaction(TransactionType type) { + // TODO - Take advantage of "type" + std::unique_ptr transaction(new Transaction(*this)); transaction->Begin(); return transaction.release(); diff -r 19ea4ecd6d9a -r 648defffc8cc OrthancServer/Plugins/Engine/OrthancPluginDatabase.h --- a/OrthancServer/Plugins/Engine/OrthancPluginDatabase.h Mon Mar 08 15:13:25 2021 +0100 +++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabase.h Mon Mar 08 16:04:56 2021 +0100 @@ -297,7 +297,7 @@ bool isProtected) ORTHANC_OVERRIDE; - virtual IDatabaseWrapper::ITransaction* StartTransaction() + virtual IDatabaseWrapper::ITransaction* StartTransaction(TransactionType type) ORTHANC_OVERRIDE; virtual void SetListener(IDatabaseListener& listener) diff -r 19ea4ecd6d9a -r 648defffc8cc OrthancServer/Sources/Database/IDatabaseWrapper.h --- a/OrthancServer/Sources/Database/IDatabaseWrapper.h Mon Mar 08 15:13:25 2021 +0100 +++ b/OrthancServer/Sources/Database/IDatabaseWrapper.h Mon Mar 08 16:04:56 2021 +0100 @@ -195,7 +195,7 @@ virtual void SetProtectedPatient(int64_t internalId, bool isProtected) = 0; - virtual ITransaction* StartTransaction() = 0; + virtual ITransaction* StartTransaction(TransactionType type) = 0; virtual void SetListener(IDatabaseListener& listener) = 0; diff -r 19ea4ecd6d9a -r 648defffc8cc OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp --- a/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp Mon Mar 08 15:13:25 2021 +0100 +++ b/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp Mon Mar 08 16:04:56 2021 +0100 @@ -596,7 +596,7 @@ } - class SQLiteDatabaseWrapper::Transaction : public IDatabaseWrapper::ITransaction + class SQLiteDatabaseWrapper::ReadWriteTransaction : public IDatabaseWrapper::ITransaction { private: SQLiteDatabaseWrapper& that_; @@ -604,7 +604,7 @@ int64_t initialDiskSize_; public: - Transaction(SQLiteDatabaseWrapper& that) : + ReadWriteTransaction(SQLiteDatabaseWrapper& that) : that_(that), transaction_(new SQLite::Transaction(that_.db_)) { @@ -637,11 +637,41 @@ }; - IDatabaseWrapper::ITransaction* SQLiteDatabaseWrapper::StartTransaction() + class SQLiteDatabaseWrapper::ReadOnlyTransaction : public IDatabaseWrapper::ITransaction { - std::unique_ptr transaction(new Transaction(*this)); - transaction->Begin(); - return transaction.release(); + public: + virtual void Rollback() ORTHANC_OVERRIDE + { + } + + virtual void Commit(int64_t fileSizeDelta /* only used in debug */) ORTHANC_OVERRIDE + { + if (fileSizeDelta != 0) + { + throw OrthancException(ErrorCode_InternalError); + } + } + }; + + + IDatabaseWrapper::ITransaction* SQLiteDatabaseWrapper::StartTransaction(TransactionType type) + { + switch (type) + { + case TransactionType_ReadOnly: + return new ReadOnlyTransaction; // This is a no-op transaction in SQLite (thanks to mutex) + + case TransactionType_ReadWrite: + { + std::unique_ptr transaction; + transaction.reset(new ReadWriteTransaction(*this)); + transaction->Begin(); + return transaction.release(); + } + + default: + throw OrthancException(ErrorCode_InternalError); + } } diff -r 19ea4ecd6d9a -r 648defffc8cc OrthancServer/Sources/Database/SQLiteDatabaseWrapper.h --- a/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.h Mon Mar 08 15:13:25 2021 +0100 +++ b/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.h Mon Mar 08 16:04:56 2021 +0100 @@ -61,7 +61,8 @@ public Compatibility::ISetResourcesContent { private: - class Transaction; + class ReadOnlyTransaction; + class ReadWriteTransaction; class LookupFormatter; IDatabaseListener* listener_; @@ -124,7 +125,7 @@ virtual void GetLastChange(std::list& target /*out*/) ORTHANC_OVERRIDE; - virtual IDatabaseWrapper::ITransaction* StartTransaction() + virtual IDatabaseWrapper::ITransaction* StartTransaction(TransactionType type) ORTHANC_OVERRIDE; virtual void FlushToDisk() diff -r 19ea4ecd6d9a -r 648defffc8cc OrthancServer/Sources/ServerEnumerations.h --- a/OrthancServer/Sources/ServerEnumerations.h Mon Mar 08 15:13:25 2021 +0100 +++ b/OrthancServer/Sources/ServerEnumerations.h Mon Mar 08 16:04:56 2021 +0100 @@ -109,6 +109,12 @@ TransferSyntaxGroup_H265 // New in Orthanc 1.9.0 }; + enum TransactionType + { + TransactionType_ReadOnly, + TransactionType_ReadWrite + }; + /** * WARNING: Do not change the explicit values in the enumerations diff -r 19ea4ecd6d9a -r 648defffc8cc OrthancServer/Sources/ServerIndex.cpp --- a/OrthancServer/Sources/ServerIndex.cpp Mon Mar 08 15:13:25 2021 +0100 +++ b/OrthancServer/Sources/ServerIndex.cpp Mon Mar 08 16:04:56 2021 +0100 @@ -247,11 +247,12 @@ bool isCommitted_; public: - explicit Transaction(ServerIndex& index) : + explicit Transaction(ServerIndex& index, + TransactionType type) : index_(index), isCommitted_(false) { - transaction_.reset(index_.db_.StartTransaction()); + transaction_.reset(index_.db_.StartTransaction(type)); index_.listener_->StartTransaction(); } @@ -716,7 +717,7 @@ try { - Transaction t(*this); + Transaction t(*this, TransactionType_ReadWrite); IDatabaseWrapper::CreateInstanceResult status; int64_t instanceId; @@ -1199,7 +1200,7 @@ void ServerIndex::StandaloneRecycling() { // WARNING: No mutex here, do not include this as a public method - Transaction t(*this); + Transaction t(*this, TransactionType_ReadWrite); Recycle(0, ""); t.Commit(0); } @@ -1292,7 +1293,7 @@ { boost::mutex::scoped_lock lock(mutex_); - Transaction t(*this); + Transaction t(*this, TransactionType_ReadWrite); ResourceType resourceType; int64_t resourceId; @@ -1349,7 +1350,7 @@ try { - Transaction t(*this); + Transaction t(*this, TransactionType_ReadWrite); int64_t patient = -1, study = -1, series = -1, instance = -1; @@ -1660,21 +1661,32 @@ { boost::mutex::scoped_lock lock(mutex_); // TODO - REMOVE - Transaction transaction(*this); // TODO - Only if "TransactionType_SingleStatement" - if (readOperations != NULL) { - ReadOnlyTransaction t(db_); - readOperations->Apply(t); + /** + * IMPORTANT: In Orthanc <= 1.9.1, there was no transaction + * in this case. This was OK because of the presence of the + * global mutex protecting the database. + **/ + + Transaction transaction(*this, TransactionType_ReadOnly); // TODO - Only if not "TransactionType_Implicit" + { + ReadOnlyTransaction t(db_); + readOperations->Apply(t); + } + transaction.Commit(0); } else { assert(writeOperations != NULL); - ReadWriteTransaction t(db_, *this); - writeOperations->Apply(t, *listener_); + + Transaction transaction(*this, TransactionType_ReadWrite); + { + ReadWriteTransaction t(db_, *this); + writeOperations->Apply(t, *listener_); + } + transaction.Commit(0); } - - transaction.Commit(0); return; // Success } @@ -2001,7 +2013,7 @@ virtual void ApplyTuple(ReadOnlyTransaction& transaction, const Tuple& tuple) ORTHANC_OVERRIDE { - // TODO - CANDIDATE FOR "TransactionType_SingleStatement" + // TODO - CANDIDATE FOR "TransactionType_Implicit" transaction.GetAllPublicIds(tuple.get<0>(), tuple.get<1>()); } }; @@ -2028,7 +2040,7 @@ virtual void ApplyTuple(ReadOnlyTransaction& transaction, const Tuple& tuple) ORTHANC_OVERRIDE { - // TODO - CANDIDATE FOR "TransactionType_SingleStatement" + // TODO - CANDIDATE FOR "TransactionType_Implicit" transaction.GetAllPublicIds(tuple.get<0>(), tuple.get<1>(), tuple.get<2>(), tuple.get<3>()); } }; @@ -2142,7 +2154,7 @@ virtual void ApplyTuple(ReadOnlyTransaction& transaction, const Tuple& tuple) ORTHANC_OVERRIDE { - // TODO - CANDIDATE FOR "TransactionType_SingleStatement" + // TODO - CANDIDATE FOR "TransactionType_Implicit" std::list exported; bool done; @@ -2164,7 +2176,7 @@ virtual void ApplyTuple(ReadOnlyTransaction& transaction, const Tuple& tuple) ORTHANC_OVERRIDE { - // TODO - CANDIDATE FOR "TransactionType_SingleStatement" + // TODO - CANDIDATE FOR "TransactionType_Implicit" std::list exported; transaction.GetLastExportedResource(exported); @@ -2589,7 +2601,7 @@ virtual void Apply(ReadOnlyTransaction& transaction) ORTHANC_OVERRIDE { - // TODO - CANDIDATE FOR "TransactionType_SingleStatement" + // TODO - CANDIDATE FOR "TransactionType_Implicit" std::list tmp; transaction.ApplyLookupResources(tmp, NULL, query_, level_, 0); CopyListToVector(result_, tmp); @@ -2610,7 +2622,7 @@ virtual void ApplyTuple(ReadOnlyTransaction& transaction, const Tuple& tuple) ORTHANC_OVERRIDE { - // TODO - CANDIDATE FOR "TransactionType_SingleStatement" + // TODO - CANDIDATE FOR "TransactionType_Implicit" tuple.get<0>() = transaction.LookupGlobalProperty(tuple.get<1>(), tuple.get<2>()); } }; @@ -2797,7 +2809,7 @@ virtual void ApplyTuple(ReadOnlyTransaction& transaction, const Tuple& tuple) ORTHANC_OVERRIDE { - // TODO - CANDIDATE FOR "TransactionType_SingleStatement" + // TODO - CANDIDATE FOR "TransactionType_Implicit" int64_t id; tuple.get<0>() = transaction.LookupResource(id, tuple.get<1>(), tuple.get<2>()); } @@ -2818,7 +2830,7 @@ virtual void ApplyTuple(ReadOnlyTransaction& transaction, const Tuple& tuple) ORTHANC_OVERRIDE { - // TODO - CANDIDATE FOR "TransactionType_SingleStatement" + // TODO - CANDIDATE FOR "TransactionType_Implicit" tuple.get<0>() = transaction.GetDatabaseVersion(); } }; @@ -2900,7 +2912,7 @@ virtual void ApplyTuple(ReadOnlyTransaction& transaction, const Tuple& tuple) ORTHANC_OVERRIDE { - // TODO - CANDIDATE FOR "TransactionType_SingleStatement" + // TODO - CANDIDATE FOR "TransactionType_Implicit" if (tuple.get<0>()) { transaction.ApplyLookupResources(resourcesList_, &instancesList_, tuple.get<1>(), tuple.get<2>(), tuple.get<3>());