我在使用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,则修改将发生两次,这会导致问题。
你是否在循环中调用这个保存方法?或者你是否在谈论这是跨连接的问题,因为两个用户几乎在同一时间点击此资源? – 2009-06-01 18:29:37
后一种情况。 – Ree 2009-06-01 18:34:52
如果这是一个基于浏览器的应用程序,它们不必在同一时间。以此示例为例:人A和B在某个时间点加载相同的数据行。人A进行更改并保存,屏幕重新加载,数据看起来不错。 C人员加载屏幕,确认人员A的变更。人B最终保存数据。人A加载数据,但他们的改变现在不见了。 – 2009-06-01 18:51:33