From 112db878d978efac007161a10f55f05202c4736f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Mon, 4 Jun 2018 10:41:20 +0200 Subject: [PATCH 1/3] Add Lock's PdoStore documentation --- components/lock.rst | 88 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 11 deletions(-) diff --git a/components/lock.rst b/components/lock.rst index 0d851dca8cc..e6ba131ef45 100644 --- a/components/lock.rst +++ b/components/lock.rst @@ -173,6 +173,7 @@ Store Scope Blocking Expiring ============================================ ====== ======== ======== :ref:`FlockStore ` local yes no :ref:`MemcachedStore ` remote no yes +:ref:`PdoStore ` remote no yes :ref:`RedisStore ` remote no yes :ref:`SemaphoreStore ` local yes no ============================================ ====== ======== ======== @@ -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: @@ -217,6 +218,46 @@ support blocking, and expects a TTL to avoid stalled locks:: Memcached does not support TTL lower than 1 second. +.. _lock-store-pdo: + +PdoStore +~~~~~~~~ + + +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; + + + // 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 @@ -290,11 +331,11 @@ the component is used in the following way. Remote Stores ~~~~~~~~~~~~~ -Remote stores (:ref:`MemcachedStore ` and -:ref:`RedisStore `) 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 `, +:ref:`PdoStore ` and :ref:`RedisStore `) 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, caching, fork, ...). .. caution:: @@ -313,11 +354,11 @@ different machines may allow two different processes to acquire the same ``Lock` Expiring Stores ~~~~~~~~~~~~~~~ -Expiring stores (:ref:`MemcachedStore ` and -:ref:`RedisStore `) 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 `, +:ref:`PdoStore ` and :ref:`RedisStore `) +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()`` @@ -431,6 +472,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 +~~~~~~~~~~ + +Pdo stores rely on the `ACID`_ properties of the SQL engine. + +.. caution:: + + In a cluster configured with multiple master, ensure writes are + synchronously propaged to every nodes, or always use the same node. + +.. caution:: + + Some SQL engine like MySQL allows to disable unique constraint check. + 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 +expiration date reference. This mechanism relies on all client and server nodes +to have synchronized clock. + +.. caution:: + + To ensure locks don't expire prematurely; the ttl's should be set with + enough extra time to account for any clock drift between nodes. + RedisStore ~~~~~~~~~~ @@ -501,6 +566,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 From 2a7923b0f2d54658b81df6d095fed7d8877d7427 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Mon, 9 Jul 2018 12:02:56 +0200 Subject: [PATCH 2/3] Add verisonAdded --- components/lock.rst | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/components/lock.rst b/components/lock.rst index e6ba131ef45..527d5d14272 100644 --- a/components/lock.rst +++ b/components/lock.rst @@ -196,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 Pdo, Redis or Memcached. + drive or a remote store based on PDO, Redis or Memcached. .. _lock-store-memcached: @@ -223,6 +223,9 @@ support blocking, and expects a TTL to avoid stalled locks:: 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 @@ -475,12 +478,12 @@ method uses the Memcached's ``flush()`` method which purges and removes everythi PdoStore ~~~~~~~~~~ -Pdo stores rely on the `ACID`_ properties of the SQL engine. +The PdoStore rely on the `ACID`_ properties of the SQL engine. .. caution:: In a cluster configured with multiple master, ensure writes are - synchronously propaged to every nodes, or always use the same node. + synchronously propagated to every nodes, or always use the same node. .. caution:: @@ -488,8 +491,8 @@ Pdo stores rely on the `ACID`_ properties of the SQL engine. 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 -expiration date reference. This mechanism relies on all client and server nodes -to have synchronized clock. +expiration date reference. This mechanism relies on all server nodes to +have synchronized clock. .. caution:: From ac621e59ef0d648ff760bdd21552ee6d9cee610f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Tue, 4 Sep 2018 19:08:21 +0200 Subject: [PATCH 3/3] Fix typo --- components/lock.rst | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/components/lock.rst b/components/lock.rst index 527d5d14272..70b8f853d60 100644 --- a/components/lock.rst +++ b/components/lock.rst @@ -233,7 +233,6 @@ support blocking, and expects a TTL to avoid stalled locks:: use Symfony\Component\Lock\Store\PdoStore; - // 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']); @@ -336,7 +335,7 @@ Remote Stores Remote stores (:ref:`MemcachedStore `, :ref:`PdoStore ` and :ref:`RedisStore `) use -an unique token to recognize the true owner of the lock. This token is stored +a 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, caching, fork, ...). @@ -478,25 +477,25 @@ method uses the Memcached's ``flush()`` method which purges and removes everythi PdoStore ~~~~~~~~~~ -The PdoStore rely on the `ACID`_ properties of the SQL engine. +The PdoStore relies on the `ACID`_ properties of the SQL engine. .. caution:: - In a cluster configured with multiple master, ensure writes are + In a cluster configured with multiple primaries, ensure writes are synchronously propagated to every nodes, or always use the same node. .. caution:: - Some SQL engine like MySQL allows to disable unique constraint check. + Some SQL engines like MySQL allow to disable the unique constraint check. 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 +In order to purge old locks, this store uses a current datetime to define an expiration date reference. This mechanism relies on all server nodes to -have synchronized clock. +have synchronized clocks. .. caution:: - To ensure locks don't expire prematurely; the ttl's should be set with + To ensure locks don't expire prematurely; the TTLs should be set with enough extra time to account for any clock drift between nodes. RedisStore