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