Answer the question
In order to leave comments, you need to log in
Yii2 transactions and model events/behaviors?
Good afternoon!
I did not find information about the organization of the logic of the interaction of events / behaviors while maintaining their entities and processing emerging events.
For example:
There is a User entity with an afterUpdate event, upon occurrence of which some kind of logic occurs (for example, change logging).
There is a UserImage entity associated with User, which creates a file in the file system before saving.
Sample code:
class UserBehavior extends \yii\base\Behavior
{
public function events()
{
return [
\yii\db\ActiveRecord::EVENT_AFTER_UPDATE => [$this, 'afterUpdate'],
];
}
public function afterUpdate(\yii\base\Event $event)
{
//логика логирования, например в файл или сторонний сервис
}
}
class User extends \yii\db\ActiveRecord
{
public function behaviors()
{
return [
UserBehavior::className(),
];
}
}
class UserImageBehavior extends \yii\base\Behavior
{
public function events()
{
return [
\yii\db\ActiveRecord::EVENT_BEFORE_INSERT => [$this, 'beforeInsert'],
\yii\db\ActiveRecord::EVENT_BEFORE_UPDATE => [$this, 'beforeUpdate'],
];
}
public function beforeInsert(\yii\base\Event $event)
{
$this->saveFile($event);
}
public function beforeUpdate(\yii\base\Event $event)
{
$this->saveFile($event);
}
protected function saveFile(\yii\base\Event $event)
{
//логика сохранения файл
//выбрасываем исключение, например не доступна файловая система
throw new \yii\base\ErrorException('The file system is not available');
}
}
class UserImage extends \yii\db\ActiveRecord
{
public function behaviors()
{
return [
UserImageBehavior::className(),
];
}
}
$user = new User();
$userImage = new UserImage();
$user->load($data);
$userImage->load($data);
$transaction = Yii::$app->db->beginTransaction();
try {
$saved = $user->save();
$userImage->user_id = $user->primaryKey;
$saved = $userImage->save() && $saved;
} catch (\Exception $e) {
$saved = false;
}
$saved ? $transaction->commit() : $transaction->rollBack();
Answer the question
In order to leave comments, you need to log in
If your log (log) goes to a service that does not have a reversing function, then you can implement a reversing function using a temporary log in a table of the same database so that there is a transactional relationship. Merge log queues by transactionUniqueID. Then we clean the records by rollback, and by commit we send the log to the service and then we clean the records. Such a delayed queue that is executed only on the after_commit event.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question