Skip to content

Add Lock's PdoStore documentation #9875

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 80 additions & 11 deletions components/lock.rst
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ Store Scope Blocking Expiring
============================================ ====== ======== ========
:ref:`FlockStore <lock-store-flock>` local yes no
:ref:`MemcachedStore <lock-store-memcached>` remote no yes
:ref:`PdoStore <lock-store-pdo>` remote no yes
:ref:`RedisStore <lock-store-redis>` remote no yes
:ref:`SemaphoreStore <lock-store-semaphore>` local yes no
============================================ ====== ======== ========
Expand All @@ -195,7 +196,7 @@ PHP process is terminated::

Beware that some file systems (such as some types of NFS) do not support
locking. In those cases, it's better to use a directory on a local disk
drive or a remote store based on Redis or Memcached.
drive or a remote store based on PDO, Redis or Memcached.

.. _lock-store-memcached:

Expand All @@ -217,6 +218,49 @@ support blocking, and expects a TTL to avoid stalled locks::

Memcached does not support TTL lower than 1 second.

.. _lock-store-pdo:

PdoStore
~~~~~~~~

.. versionadded:: 4.2
The PdoStore was introduced Symfony 4.2.


The PdoStore saves locks in an SQL database, it requires a `PDO`_,
`Doctrine DBAL Connection`_, or `Data Source Name (DSN)`_. This store does not
support blocking, and expects a TTL to avoid stalled locks::

use Symfony\Component\Lock\Store\PdoStore;


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra blank line

// a PDO, a Doctrine DBAL connection or DSN for lazy connecting through PDO
$databaseConnectionOrDSN = 'mysql:host=127.0.0.1;dbname=lock';
$store = new PdoStore($databaseConnectionOrDSN, ['db_username' => 'myuser', 'db_password' => 'mypassword']);

.. note::

This store does not support TTL lower than 1 second.

Before storing locks in the database, you must create the table that stores
the information. The store provides a method called
:method:`Symfony\\Component\\Lock\\Store\\PdoStore::createTable`
to set up this table for you according to the database engine used::

try {
$store->createTable();
} catch (\PDOException $exception) {
// the table could not be created for some reason
}

A great way to set up the table on production is to call the method on a dev
enviroment, then generate a migration:

.. code-block:: terminal

$ php bin/console doctrine:migrations:diff
$ php bin/console doctrine:migrations:migrate

.. _lock-store-redis:

RedisStore
Expand Down Expand Up @@ -290,11 +334,11 @@ the component is used in the following way.
Remote Stores
~~~~~~~~~~~~~

Remote stores (:ref:`MemcachedStore <lock-store-memcached>` and
:ref:`RedisStore <lock-store-redis>`) use an unique token to recognize the true
owner of the lock. This token is stored in the
:class:`Symfony\\Component\\Lock\\Key` object and is used internally by the
``Lock``, therefore this key must not be shared between processes (session,
Remote stores (:ref:`MemcachedStore <lock-store-memcached>`,
:ref:`PdoStore <lock-store-pdo>` and :ref:`RedisStore <lock-store-redis>`) use
an unique token to recognize the true owner of the lock. This token is stored
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a unique

in the :class:`Symfony\\Component\\Lock\\Key` object and is used internally by
the ``Lock``, therefore this key must not be shared between processes (session,
caching, fork, ...).

.. caution::
Expand All @@ -313,11 +357,11 @@ different machines may allow two different processes to acquire the same ``Lock`
Expiring Stores
~~~~~~~~~~~~~~~

Expiring stores (:ref:`MemcachedStore <lock-store-memcached>` and
:ref:`RedisStore <lock-store-redis>`) guarantee that the lock is acquired
only for the defined duration of time. If the task takes longer to be
accomplished, then the lock can be released by the store and acquired by
someone else.
Expiring stores (:ref:`MemcachedStore <lock-store-memcached>`,
:ref:`PdoStore <lock-store-pdo>` and :ref:`RedisStore <lock-store-redis>`)
guarantee that the lock is acquired only for the defined duration of time. If
the task takes longer to be accomplished, then the lock can be released by the
store and acquired by someone else.

The ``Lock`` provides several methods to check its health. The ``isExpired()``
method checks whether or not it lifetime is over and the ``getRemainingLifetime()``
Expand Down Expand Up @@ -431,6 +475,30 @@ method uses the Memcached's ``flush()`` method which purges and removes everythi
The method ``flush()`` must not be called, or locks should be stored in a
dedicated Memcached service away from Cache.

PdoStore
~~~~~~~~~~

The PdoStore rely on the `ACID`_ properties of the SQL engine.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

relies


.. caution::

In a cluster configured with multiple master, ensure writes are
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

multiple masters

synchronously propagated to every nodes, or always use the same node.

.. caution::

Some SQL engine like MySQL allows to disable unique constraint check.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SQL engines ... allow ... disable the unique ...

Ensure that this is not the case ``SET unique_checks=1;``.

In order to purge old lock, this store use a current datetime to define a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

old locks, this store uses

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

an expiration

expiration date reference. This mechanism relies on all server nodes to
have synchronized clock.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clocks


.. caution::

To ensure locks don't expire prematurely; the ttl's should be set with
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TTLs

enough extra time to account for any clock drift between nodes.

RedisStore
~~~~~~~~~~

Expand Down Expand Up @@ -501,6 +569,7 @@ instance, during the deployment of a new version. Processes with new
configuration must not be started while old processes with old configuration
are still running.

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