diff --git a/README.md b/README.md index b3f3db73..b0b40677 100644 --- a/README.md +++ b/README.md @@ -71,10 +71,11 @@ The `Mutex` is an abstract class. You will have to chose an implementation: - [`PredisMutex`](#predismutex) - [`SemaphoreMutex`](#semaphoremutex) - [`TransactionalMutex`](#transactionalmutex) +- [`MySQLMutex`](#mysqlmutex) #### CASMutex -The [`CASMutex`](http://malkusch.github.io/lock/api/class-malkusch.lock.mutex.CASMutex.html) +The **CASMutex** has to be used with a [Compare-and-swap](https://en.wikipedia.org/wiki/Compare-and-swap) operation. This mutex is lock free. It will repeat executing the code until the CAS operation was successful. The code should therefore notify the mutex by calling @@ -99,8 +100,7 @@ $mutex->synchronized(function () use ($memcached, $mutex, $amount) { #### FlockMutex -The [`FlockMutex`](http://malkusch.github.io/lock/api/class-malkusch.lock.mutex.FlockMutex.html) -is a lock implementation based on [`flock()`](http://php.net/manual/en/function.flock.php). +The **FlockMutex** is a lock implementation based on [`flock()`](http://php.net/manual/en/function.flock.php). Example: ```php @@ -118,7 +118,7 @@ $mutex->synchronized(function () use ($bankAccount, $amount) { #### MemcachedMutex -The [`MemcachedMutex`](http://malkusch.github.io/lock/api/class-malkusch.lock.mutex.MemcachedMutex.html) +The **MemcachedMutex** is a spinlock implementation which uses the [`Memcached` API](http://php.net/manual/en/book.memcached.php). Example: @@ -140,11 +140,10 @@ $mutex->synchronized(function () use ($bankAccount, $amount) { #### PHPRedisMutex -The [`PHPRedisMutex`](http://malkusch.github.io/lock/api/class-malkusch.lock.mutex.PHPRedisMutex.html) -is the distributed lock implementation of [RedLock](http://redis.io/topics/distlock) +The **PHPRedisMutex** is the distributed lock implementation of [RedLock](http://redis.io/topics/distlock) which uses the [`phpredis` extension](https://github.com/phpredis/phpredis). -This implementation requires at least phpredis-2.2.4. +This implementation requires at least `phpredis-2.2.4`. Example: ```php @@ -165,8 +164,7 @@ $mutex->synchronized(function () use ($bankAccount, $amount) { #### PredisMutex -The [`PredisMutex`](http://malkusch.github.io/lock/api/class-malkusch.lock.mutex.PredisMutex.html) -is the distributed lock implementation of [RedLock](http://redis.io/topics/distlock) +The **PredisMutex** is the distributed lock implementation of [RedLock](http://redis.io/topics/distlock) which uses the [`Predis` API](https://github.com/nrk/predis). Example: @@ -187,7 +185,7 @@ $mutex->synchronized(function () use ($bankAccount, $amount) { #### SemaphoreMutex -The [`SemaphoreMutex`](http://malkusch.github.io/lock/api/class-malkusch.lock.mutex.SemaphoreMutex.html) +The **SemaphoreMutex** is a lock implementation based on [Semaphore](http://php.net/manual/en/ref.sem.php). Example: @@ -207,7 +205,7 @@ $mutex->synchronized(function () use ($bankAccount, $amount) { #### TransactionalMutex -The [`TransactionalMutex`](http://malkusch.github.io/lock/api/class-malkusch.lock.mutex.TransactionalMutex.html) +The **TransactionalMutex** delegates the serialization to the DBS. The exclusive code is executed within a transaction. It's up to you to set the correct transaction isolation level. However if the transaction fails (i.e. a `PDOException` was thrown), the code @@ -234,6 +232,36 @@ $mutex->synchronized(function () use ($pdo, $accountId, $amount) { }); ``` + +#### MySQLMutex + +The **MySQLMutex** uses MySQL's +[`GET_LOCK`](https://dev.mysql.com/doc/refman/8.0/en/miscellaneous-functions.html#function_get-lock) +function to create lock back end. + +It supports time outs. If the connection to the database server is lost or interrupted, the lock is +automatically released. + +Note that before MySQL 5.7.5 you cannot use nested locks, any new lock will silently release already +held locks. You should probably refrain from using this mutex on MySQL versions < 5.7.5. + +```php +$pdo = new PDO("mysql:host=localhost;dbname=test", "username"); + +$mutex = new MySQLMutex($pdo, "balance", 15); +$mutex->synchronized(function () use ($bankAccount, $amount) { + $balance = $bankAccount->getBalance(); + $balance -= $amount; + if ($balance < 0) { + throw new \DomainException("You have no credit."); + + } + $bankAccount->setBalance($balance); +}); +``` + + + # License and authors This project is free and under the WTFPL.