Skip to content

Commit 112db87

Browse files
committed
Add Lock's PdoStore documentation
1 parent 12e7969 commit 112db87

File tree

1 file changed

+77
-11
lines changed

1 file changed

+77
-11
lines changed

components/lock.rst

Lines changed: 77 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ Store Scope Blocking Expiring
173173
============================================ ====== ======== ========
174174
:ref:`FlockStore <lock-store-flock>` local yes no
175175
:ref:`MemcachedStore <lock-store-memcached>` remote no yes
176+
:ref:`PdoStore <lock-store-pdo>` remote no yes
176177
:ref:`RedisStore <lock-store-redis>` remote no yes
177178
:ref:`SemaphoreStore <lock-store-semaphore>` local yes no
178179
============================================ ====== ======== ========
@@ -195,7 +196,7 @@ PHP process is terminated::
195196

196197
Beware that some file systems (such as some types of NFS) do not support
197198
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.
199200

200201
.. _lock-store-memcached:
201202

@@ -217,6 +218,46 @@ support blocking, and expects a TTL to avoid stalled locks::
217218

218219
Memcached does not support TTL lower than 1 second.
219220

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+
220261
.. _lock-store-redis:
221262

222263
RedisStore
@@ -290,11 +331,11 @@ the component is used in the following way.
290331
Remote Stores
291332
~~~~~~~~~~~~~
292333

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,
298339
caching, fork, ...).
299340

300341
.. caution::
@@ -313,11 +354,11 @@ different machines may allow two different processes to acquire the same ``Lock`
313354
Expiring Stores
314355
~~~~~~~~~~~~~~~
315356

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.
321362

322363
The ``Lock`` provides several methods to check its health. The ``isExpired()``
323364
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
431472
The method ``flush()`` must not be called, or locks should be stored in a
432473
dedicated Memcached service away from Cache.
433474

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+
434499
RedisStore
435500
~~~~~~~~~~
436501

@@ -501,6 +566,7 @@ instance, during the deployment of a new version. Processes with new
501566
configuration must not be started while old processes with old configuration
502567
are still running.
503568

569+
.. _`ACID`: https://en.wikipedia.org/wiki/ACID
504570
.. _`locks`: https://en.wikipedia.org/wiki/Lock_(computer_science)
505571
.. _Packagist: https://packagist.org/packages/symfony/lock
506572
.. _`PHP semaphore functions`: http://php.net/manual/en/book.sem.php

0 commit comments

Comments
 (0)