Mercurial > hg > orthanc-databases
annotate Framework/PostgreSQL/PostgreSQLDatabase.cpp @ 135:e26690365c25
MySQL: Added an advisory lock to avoid race conditions during database setup
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 08 May 2019 21:09:18 +0200 |
parents | cc3dc759c989 |
children | 4cd7e45b671e |
rev | line source |
---|---|
0 | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
67 | 5 * Copyright (C) 2017-2019 Osimis S.A., Belgium |
0 | 6 * |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU Affero General Public License | |
9 * as published by the Free Software Foundation, either version 3 of | |
10 * the License, or (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Affero General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Affero General Public License | |
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 **/ | |
20 | |
21 | |
107
5765cc5fd268
reverted fix for OS X that breaks other targets
Sebastien Jodogne <s.jodogne@orthanc-labs.com>
parents:
105
diff
changeset
|
22 #include "PostgreSQLIncludes.h" // Must be the first |
105 | 23 #include "PostgreSQLDatabase.h" |
0 | 24 |
25 #include "PostgreSQLResult.h" | |
26 #include "PostgreSQLStatement.h" | |
27 #include "PostgreSQLTransaction.h" | |
23
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
28 #include "../Common/ImplicitTransaction.h" |
0 | 29 |
30 #include <Core/Logging.h> | |
31 #include <Core/OrthancException.h> | |
32 | |
33 #include <boost/lexical_cast.hpp> | |
134
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
34 #include <boost/thread.hpp> |
0 | 35 |
36 | |
37 namespace OrthancDatabases | |
38 { | |
39 void PostgreSQLDatabase::ThrowException(bool log) | |
40 { | |
41 if (log) | |
42 { | |
43 LOG(ERROR) << "PostgreSQL error: " | |
44 << PQerrorMessage(reinterpret_cast<PGconn*>(pg_)); | |
45 } | |
46 | |
47 if (PQstatus(reinterpret_cast<PGconn*>(pg_)) == CONNECTION_OK) | |
48 { | |
49 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); | |
50 } | |
51 else | |
52 { | |
53 throw Orthanc::OrthancException(Orthanc::ErrorCode_DatabaseUnavailable); | |
54 } | |
55 } | |
56 | |
57 | |
58 void PostgreSQLDatabase::Close() | |
59 { | |
60 if (pg_ != NULL) | |
61 { | |
62 LOG(INFO) << "Closing connection to PostgreSQL"; | |
63 PQfinish(reinterpret_cast<PGconn*>(pg_)); | |
64 pg_ = NULL; | |
65 } | |
66 } | |
67 | |
46
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
68 |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
69 PostgreSQLDatabase::~PostgreSQLDatabase() |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
70 { |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
71 try |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
72 { |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
73 Close(); |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
74 } |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
75 catch (Orthanc::OrthancException&) |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
76 { |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
77 // Ignore possible exceptions due to connection loss |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
78 } |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
79 } |
6a574d810b98
Compatibility with MySQL 8.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
29
diff
changeset
|
80 |
0 | 81 |
82 void PostgreSQLDatabase::Open() | |
83 { | |
84 if (pg_ != NULL) | |
85 { | |
86 // Already connected | |
87 return; | |
88 } | |
89 | |
90 std::string s; | |
91 parameters_.Format(s); | |
92 | |
93 pg_ = PQconnectdb(s.c_str()); | |
94 | |
95 if (pg_ == NULL || | |
96 PQstatus(reinterpret_cast<PGconn*>(pg_)) != CONNECTION_OK) | |
97 { | |
98 std::string message; | |
99 | |
100 if (pg_) | |
101 { | |
102 message = PQerrorMessage(reinterpret_cast<PGconn*>(pg_)); | |
103 PQfinish(reinterpret_cast<PGconn*>(pg_)); | |
104 pg_ = NULL; | |
105 } | |
106 | |
107 LOG(ERROR) << "PostgreSQL error: " << message; | |
108 throw Orthanc::OrthancException(Orthanc::ErrorCode_DatabaseUnavailable); | |
109 } | |
12
41543239072d
transactions for storage area
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
110 } |
0 | 111 |
112 | |
134
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
113 bool PostgreSQLDatabase::RunAdvisoryLockStatement(const std::string& statement) |
12
41543239072d
transactions for storage area
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
114 { |
41543239072d
transactions for storage area
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
115 PostgreSQLTransaction transaction(*this); |
0 | 116 |
134
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
117 Query query(statement, false); |
29 | 118 PostgreSQLStatement s(*this, query); |
0 | 119 |
12
41543239072d
transactions for storage area
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
120 PostgreSQLResult result(s); |
134
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
121 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
122 bool success = (!result.IsDone() && |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
123 result.GetBoolean(0)); |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
124 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
125 transaction.Commit(); |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
126 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
127 return success; |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
128 } |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
129 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
130 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
131 bool PostgreSQLDatabase::AcquireAdvisoryLock(int32_t lock) |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
132 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
133 return RunAdvisoryLockStatement( |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
134 "select pg_try_advisory_lock(" + |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
135 boost::lexical_cast<std::string>(lock) + ")"); |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
136 } |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
137 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
138 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
139 bool PostgreSQLDatabase::ReleaseAdvisoryLock(int32_t lock) |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
140 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
141 return RunAdvisoryLockStatement( |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
142 "select pg_advisory_unlock(" + |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
143 boost::lexical_cast<std::string>(lock) + ")"); |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
144 } |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
145 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
146 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
147 void PostgreSQLDatabase::AdvisoryLock(int32_t lock) |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
148 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
149 if (!AcquireAdvisoryLock(lock)) |
12
41543239072d
transactions for storage area
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
150 { |
41543239072d
transactions for storage area
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
151 LOG(ERROR) << "The PostgreSQL database is locked by another instance of Orthanc"; |
41543239072d
transactions for storage area
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
152 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); |
41543239072d
transactions for storage area
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
153 } |
0 | 154 } |
155 | |
156 | |
157 void PostgreSQLDatabase::Execute(const std::string& sql) | |
158 { | |
159 LOG(TRACE) << "PostgreSQL: " << sql; | |
160 Open(); | |
161 | |
162 PGresult* result = PQexec(reinterpret_cast<PGconn*>(pg_), sql.c_str()); | |
163 if (result == NULL) | |
164 { | |
165 ThrowException(true); | |
166 } | |
167 | |
168 bool ok = (PQresultStatus(result) == PGRES_COMMAND_OK || | |
169 PQresultStatus(result) == PGRES_TUPLES_OK); | |
170 | |
171 if (ok) | |
172 { | |
173 PQclear(result); | |
174 } | |
175 else | |
176 { | |
177 std::string message = PQresultErrorMessage(result); | |
178 PQclear(result); | |
179 | |
180 LOG(ERROR) << "PostgreSQL error: " << message; | |
181 ThrowException(false); | |
182 } | |
183 } | |
184 | |
185 | |
186 bool PostgreSQLDatabase::DoesTableExist(const char* name) | |
187 { | |
188 std::string lower(name); | |
189 std::transform(lower.begin(), lower.end(), lower.begin(), tolower); | |
190 | |
191 // http://stackoverflow.com/a/24089729/881731 | |
192 | |
193 PostgreSQLStatement statement(*this, | |
194 "SELECT 1 FROM pg_catalog.pg_class c " | |
195 "JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace " | |
196 "WHERE n.nspname = 'public' AND c.relkind='r' " | |
197 "AND c.relname=$1", true); | |
198 | |
199 statement.DeclareInputString(0); | |
200 statement.BindString(0, lower); | |
201 | |
202 PostgreSQLResult result(statement); | |
203 return !result.IsDone(); | |
204 } | |
205 | |
206 | |
207 void PostgreSQLDatabase::ClearAll() | |
208 { | |
209 PostgreSQLTransaction transaction(*this); | |
210 | |
211 // Remove all the large objects | |
212 Execute("SELECT lo_unlink(loid) FROM (SELECT DISTINCT loid FROM pg_catalog.pg_largeobject) as loids;"); | |
213 | |
214 // http://stackoverflow.com/a/21247009/881731 | |
215 Execute("DROP SCHEMA public CASCADE;"); | |
216 Execute("CREATE SCHEMA public;"); | |
217 Execute("GRANT ALL ON SCHEMA public TO postgres;"); | |
218 Execute("GRANT ALL ON SCHEMA public TO public;"); | |
219 Execute("COMMENT ON SCHEMA public IS 'standard public schema';"); | |
220 | |
221 transaction.Commit(); | |
222 } | |
223 | |
224 | |
225 IPrecompiledStatement* PostgreSQLDatabase::Compile(const Query& query) | |
226 { | |
227 return new PostgreSQLStatement(*this, query); | |
228 } | |
229 | |
230 | |
23
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
231 namespace |
0 | 232 { |
23
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
233 class PostgreSQLImplicitTransaction : public ImplicitTransaction |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
234 { |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
235 private: |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
236 PostgreSQLDatabase& db_; |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
237 |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
238 protected: |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
239 virtual IResult* ExecuteInternal(IPrecompiledStatement& statement, |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
240 const Dictionary& parameters) |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
241 { |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
242 return dynamic_cast<PostgreSQLStatement&>(statement).Execute(*this, parameters); |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
243 } |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
244 |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
245 virtual void ExecuteWithoutResultInternal(IPrecompiledStatement& statement, |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
246 const Dictionary& parameters) |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
247 { |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
248 dynamic_cast<PostgreSQLStatement&>(statement).ExecuteWithoutResult(*this, parameters); |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
249 } |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
250 |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
251 public: |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
252 PostgreSQLImplicitTransaction(PostgreSQLDatabase& db) : |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
253 db_(db) |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
254 { |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
255 } |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
256 }; |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
257 } |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
258 |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
259 |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
260 ITransaction* PostgreSQLDatabase::CreateTransaction(bool isImplicit) |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
261 { |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
262 if (isImplicit) |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
263 { |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
264 return new PostgreSQLImplicitTransaction(*this); |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
265 } |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
266 else |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
267 { |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
268 return new PostgreSQLTransaction(*this); |
b2ff1cd2907a
handling of implicit transactions in DatabaseManager
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
12
diff
changeset
|
269 } |
0 | 270 } |
134
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
271 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
272 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
273 PostgreSQLDatabase::TransientAdvisoryLock::TransientAdvisoryLock( |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
274 PostgreSQLDatabase& database, |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
275 int32_t lock) : |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
276 database_(database), |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
277 lock_(lock) |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
278 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
279 bool locked = true; |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
280 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
281 for (unsigned int i = 0; i < 10; i++) |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
282 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
283 if (database_.AcquireAdvisoryLock(lock_)) |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
284 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
285 locked = false; |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
286 break; |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
287 } |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
288 else |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
289 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
290 boost::this_thread::sleep(boost::posix_time::milliseconds(500)); |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
291 } |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
292 } |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
293 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
294 if (locked) |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
295 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
296 LOG(ERROR) << "Cannot acquire a transient advisory lock"; |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
297 throw Orthanc::OrthancException(Orthanc::ErrorCode_Plugin); |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
298 } |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
299 } |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
300 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
301 |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
302 PostgreSQLDatabase::TransientAdvisoryLock::~TransientAdvisoryLock() |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
303 { |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
304 database_.ReleaseAdvisoryLock(lock_); |
cc3dc759c989
Added an advisory lock to avoid race conditions during database setup
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
107
diff
changeset
|
305 } |
0 | 306 } |