我在使用 MySQL 和 PHP + Propel 1.3 时遇到了似乎是并发问题。下面是一个 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 对象的表,以便后续事务只有在第一个事务完成工作后才能从中读取?
编辑:上下文是一个 Web 应用程序。简而言之,在某些情况下,我希望第一个请求进行一些数据修改(这发生在获取和保存 $foo 之间)。所有后续请求都不应进行修改。是否会发生修改取决于获取的 $foo 状态(表行属性)。如果两个事务获取相同的 $foo,则修改将发生两次,这会导致问题。