MysqlMutex.php 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\mutex;
  8. use yii\base\InvalidConfigException;
  9. /**
  10. * MysqlMutex implements mutex "lock" mechanism via MySQL locks.
  11. *
  12. * Application configuration example:
  13. *
  14. * ```
  15. * [
  16. * 'components' => [
  17. * 'db' => [
  18. * 'class' => 'yii\db\Connection',
  19. * 'dsn' => 'mysql:host=127.0.0.1;dbname=demo',
  20. * ]
  21. * 'mutex' => [
  22. * 'class' => 'yii\mutex\MysqlMutex',
  23. * ],
  24. * ],
  25. * ]
  26. * ```
  27. *
  28. * @see Mutex
  29. *
  30. * @author resurtm <resurtm@gmail.com>
  31. * @since 2.0
  32. */
  33. class MysqlMutex extends DbMutex
  34. {
  35. /**
  36. * Initializes MySQL specific mutex component implementation.
  37. * @throws InvalidConfigException if [[db]] is not MySQL connection.
  38. */
  39. public function init()
  40. {
  41. parent::init();
  42. if ($this->db->driverName !== 'mysql') {
  43. throw new InvalidConfigException('In order to use MysqlMutex connection must be configured to use MySQL database.');
  44. }
  45. }
  46. /**
  47. * Acquires lock by given name.
  48. * @param string $name of the lock to be acquired.
  49. * @param int $timeout time (in seconds) to wait for lock to become released.
  50. * @return bool acquiring result.
  51. * @see http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_get-lock
  52. */
  53. protected function acquireLock($name, $timeout = 0)
  54. {
  55. return $this->db->useMaster(function ($db) use ($name, $timeout) {
  56. /** @var \yii\db\Connection $db */
  57. return (bool) $db->createCommand(
  58. 'SELECT GET_LOCK(:name, :timeout)',
  59. [':name' => $this->hashLockName($name), ':timeout' => $timeout]
  60. )->queryScalar();
  61. });
  62. }
  63. /**
  64. * Releases lock by given name.
  65. * @param string $name of the lock to be released.
  66. * @return bool release result.
  67. * @see http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_release-lock
  68. */
  69. protected function releaseLock($name)
  70. {
  71. return $this->db->useMaster(function ($db) use ($name) {
  72. /** @var \yii\db\Connection $db */
  73. return (bool) $db->createCommand(
  74. 'SELECT RELEASE_LOCK(:name)',
  75. [':name' => $this->hashLockName($name)]
  76. )->queryScalar();
  77. });
  78. }
  79. /**
  80. * Generate hash for lock name to avoid exceeding lock name length limit.
  81. *
  82. * @param string $name
  83. * @return string
  84. * @since 2.0.16
  85. * @see https://github.com/yiisoft/yii2/pull/16836
  86. */
  87. protected function hashLockName($name) {
  88. return sha1($name);
  89. }
  90. }