This is achieved by using a "lock" mechanism. Each possibly concurrent thread cooperates by acquiring
a lock before accessing the corresponding data.
Usage example:
if ($mutex->acquire($mutexName)) {
business logic execution
} else {
execution is blocked!
}
This is a base class, which should be extended in order to implement the actual lock mechanism.
/** * Initializes MySQL specific mutex component implementation. * @throws InvalidConfigException if [[db]] is not MySQL connection. */ public function init() { parent::init(); if ($this->db->driverName !== 'mysql') { throw new InvalidConfigException('In order to use MysqlMutex connection must be configured to use MySQL database.'); } }
/** * Initializes generic database table based mutex implementation. * @throws InvalidConfigException if [[db]] is invalid. */ public function init() { parent::init(); if (is_string($this->db)) { $this->db = Yii::$app->getComponent($this->db); } if (!$this->db instanceof Connection) { throw new InvalidConfigException('Mutex::db must be either a DB connection instance or the application component ID of a DB connection.'); } }
/** * Initializes generic database table based mutex implementation. * @throws InvalidConfigException if [[db]] is invalid. */ public function init() { parent::init(); $this->db = Instance::ensure($this->db, Connection::className()); }
/** * Acquires current action lock. * @return boolean lock acquiring result. */ protected function acquireMutex() { $this->mutex = Instance::ensure($this->mutex, Mutex::className()); return $this->mutex->acquire($this->composeMutexName()); }
/** * @return \yii\mutex\Mutex * @throws \yii\base\InvalidConfigException */ protected function getMutex() { return Instance::ensure($this->mutexID, Mutex::className()); }
/** * @inheritdoc */ public function init() { parent::init(); $this->cache = is_string($this->cache) ? Yii::$app->get($this->cache, false) : $this->cache; }