@@ -173,6 +173,7 @@ Store Scope Blocking Expiring
173
173
============================================ ====== ======== ========
174
174
:ref: `FlockStore <lock-store-flock >` local yes no
175
175
:ref: `MemcachedStore <lock-store-memcached >` remote no yes
176
+ :ref: `PdoStore <lock-store-pdo >` remote no yes
176
177
:ref: `RedisStore <lock-store-redis >` remote no yes
177
178
:ref: `SemaphoreStore <lock-store-semaphore >` local yes no
178
179
============================================ ====== ======== ========
@@ -195,7 +196,7 @@ PHP process is terminated::
195
196
196
197
Beware that some file systems (such as some types of NFS) do not support
197
198
locking. In those cases, it's better to use a directory on a local disk
198
- drive or a remote store based on Redis or Memcached.
199
+ drive or a remote store based on Pdo, Redis or Memcached.
199
200
200
201
.. _lock-store-memcached :
201
202
@@ -217,6 +218,46 @@ support blocking, and expects a TTL to avoid stalled locks::
217
218
218
219
Memcached does not support TTL lower than 1 second.
219
220
221
+ .. _lock-store-pdo :
222
+
223
+ PdoStore
224
+ ~~~~~~~~
225
+
226
+
227
+ The PdoStore saves locks in an SQL database, it requires a `PDO `_,
228
+ `Doctrine DBAL Connection `_, or `Data Source Name (DSN) `_. This store does not
229
+ support blocking, and expects a TTL to avoid stalled locks::
230
+
231
+ use Symfony\Component\Lock\Store\PdoStore;
232
+
233
+
234
+ // a PDO, a Doctrine DBAL connection or DSN for lazy connecting through PDO
235
+ $databaseConnectionOrDSN = 'mysql:host=127.0.0.1;dbname=lock';
236
+ $store = new PdoStore($databaseConnectionOrDSN, ['db_username' => 'myuser', 'db_password' => 'mypassword']);
237
+
238
+ .. note ::
239
+
240
+ This store does not support TTL lower than 1 second.
241
+
242
+ Before storing locks in the database, you must create the table that stores
243
+ the information. The store provides a method called
244
+ :method: `Symfony\\ Component\\ Lock\\ Store\\ PdoStore::createTable `
245
+ to set up this table for you according to the database engine used::
246
+
247
+ try {
248
+ $store->createTable();
249
+ } catch (\PDOException $exception) {
250
+ // the table could not be created for some reason
251
+ }
252
+
253
+ A great way to set up the table on production is to call the method on a dev
254
+ enviroment, then generate a migration:
255
+
256
+ .. code-block :: terminal
257
+
258
+ $ php bin/console doctrine:migrations:diff
259
+ $ php bin/console doctrine:migrations:migrate
260
+
220
261
.. _lock-store-redis :
221
262
222
263
RedisStore
@@ -290,11 +331,11 @@ the component is used in the following way.
290
331
Remote Stores
291
332
~~~~~~~~~~~~~
292
333
293
- Remote stores (:ref: `MemcachedStore <lock-store-memcached >` and
294
- :ref: `RedisStore <lock-store-redis >`) use an unique token to recognize the true
295
- owner of the lock. This token is stored in the
296
- :class: `Symfony\\ Component\\ Lock\\ Key ` object and is used internally by the
297
- ``Lock ``, therefore this key must not be shared between processes (session,
334
+ Remote stores (:ref: `MemcachedStore <lock-store-memcached >`,
335
+ :ref: `PdoStore < lock-store-pdo >` and :ref: ` RedisStore <lock-store-redis >`) use
336
+ an unique token to recognize the true owner of the lock. This token is stored
337
+ in the :class: `Symfony\\ Component\\ Lock\\ Key ` object and is used internally by
338
+ the ``Lock ``, therefore this key must not be shared between processes (session,
298
339
caching, fork, ...).
299
340
300
341
.. caution ::
@@ -313,11 +354,11 @@ different machines may allow two different processes to acquire the same ``Lock`
313
354
Expiring Stores
314
355
~~~~~~~~~~~~~~~
315
356
316
- Expiring stores (:ref: `MemcachedStore <lock-store-memcached >` and
317
- :ref: `RedisStore <lock-store-redis >`) guarantee that the lock is acquired
318
- only for the defined duration of time. If the task takes longer to be
319
- accomplished, then the lock can be released by the store and acquired by
320
- someone else.
357
+ Expiring stores (:ref: `MemcachedStore <lock-store-memcached >`,
358
+ :ref: `PdoStore <lock-store-pdo >` and :ref: ` RedisStore < lock-store-redis >`)
359
+ guarantee that the lock is acquired only for the defined duration of time. If
360
+ the task takes longer to be accomplished, then the lock can be released by the
361
+ store and acquired by someone else.
321
362
322
363
The ``Lock `` provides several methods to check its health. The ``isExpired() ``
323
364
method checks whether or not it lifetime is over and the ``getRemainingLifetime() ``
@@ -431,6 +472,30 @@ method uses the Memcached's ``flush()`` method which purges and removes everythi
431
472
The method ``flush() `` must not be called, or locks should be stored in a
432
473
dedicated Memcached service away from Cache.
433
474
475
+ PdoStore
476
+ ~~~~~~~~~~
477
+
478
+ Pdo stores rely on the `ACID `_ properties of the SQL engine.
479
+
480
+ .. caution ::
481
+
482
+ In a cluster configured with multiple master, ensure writes are
483
+ synchronously propaged to every nodes, or always use the same node.
484
+
485
+ .. caution ::
486
+
487
+ Some SQL engine like MySQL allows to disable unique constraint check.
488
+ Ensure that this is not the case ``SET unique_checks=1; ``.
489
+
490
+ In order to purge old lock, this store use a current datetime to define a
491
+ expiration date reference. This mechanism relies on all client and server nodes
492
+ to have synchronized clock.
493
+
494
+ .. caution ::
495
+
496
+ To ensure locks don't expire prematurely; the ttl's should be set with
497
+ enough extra time to account for any clock drift between nodes.
498
+
434
499
RedisStore
435
500
~~~~~~~~~~
436
501
@@ -501,6 +566,7 @@ instance, during the deployment of a new version. Processes with new
501
566
configuration must not be started while old processes with old configuration
502
567
are still running.
503
568
569
+ .. _`ACID` : https://en.wikipedia.org/wiki/ACID
504
570
.. _`locks` : https://en.wikipedia.org/wiki/Lock_(computer_science)
505
571
.. _Packagist : https://packagist.org/packages/symfony/lock
506
572
.. _`PHP semaphore functions` : http://php.net/manual/en/book.sem.php
0 commit comments