У меня возникли проблемы с параллелизмом при использовании MySQL и PHP + Propel 1.3. Ниже приведен небольшой пример метода «save» объекта Propel.
public function save(PropelPDO $con = null) {
$con = Propel::getConnection();
try {
$con->beginTransaction();
sleep(3); // ignore this, used for testing only
parent::save($con);
$foo = $this->getFoo(); // Propel object, triggers a SELECT
// stuff is happening here...
$foo->save($con);
$con->commit();
} catch (Exception $e) {
$con->rollBack();
throw $e;
}
}
Проблема в объекте $ foo. Допустим, мы получаем два вызова примера метода один за другим в очень короткое время. В некоторых случаях, если вторая транзакция читает $ foo ...
$foo = $this->getFoo();
... до того, как первая транзакция смогла сохранить ее ...
$foo->save($con);
... $ foo, прочитанный во второй транзакции, устареет, и произойдут плохие вещи.
Как заставить блокировать таблицу, в которой хранятся объекты Foo, чтобы последующие транзакции могли читать из нее только после того, как первая закончила свою работу?
РЕДАКТИРОВАТЬ: контекст представляет собой веб-приложение. Короче говоря, в некоторых случаях я хочу, чтобы самый первый запрос выполнял некоторую модификацию данных (что происходит между получением и сохранением $ foo). Все последующие запросы не должны быть в состоянии сделать изменения. Произойдет ли изменение или нет, зависит от извлеченного состояния $ foo (атрибут строки таблицы). Если две транзакции извлекают один и тот же $ foo, модификация будет выполняться дважды, что вызывает проблему.