我正在使用 PHP Active Record 开发一个项目,我是新手,但我真的开始喜欢上它了。所有的对象都是 ActiveRecord 模型的扩展
class User extends Model {
}
class Item extends Model {
}
.
.
.
现在我的代码将包含与此类似的内容(用户表包含属于用户的项目计数,项目表包含项目)。
$user = User::find_by_id($id);
$user->num_items++;
$item = new Item();
//Do stuff with the item
$user->save();
$item->save();
现在我担心从理论上讲,当网站受到重创时,某些东西出现故障或数据库被关闭进行维护(是的,这些事情让我很担心)。由于理论上这些语句不在事务中:
$user->save();
//User table is updated successfully
//----- MySQL goes Down Here -------/
$item->save(); //This won't run, now the user's table may say he has 4 items but he only has 3 since the last one didn't get inserted
我希望能够将用户和项目一起保存,如果失败则回滚。我知道如何在手动 MySQL 中执行此操作,但这违背了使用 ORM 的目的。
最佳答案
也许它对仍在使用这个库的人有用。 您的每个模型中都有交易方法
public static function transaction($closure)
它位于\ActiveRecord\Model 命名空间(它是您的项目模型的父类)
您可以使用此公共(public)静态方法通过闭包运行您的交易查询。 示例:
$user = User::find_by_id($id);
$item = new Item();
$entity::transaction(function() use ($user, $item) {
//Do stuff with the items...
$user->name = 'somename';
$user->save();
$item->quantity = 0;
$item->save();
});
上面的事务静态方法使用模型中的连接实例,如果每个模型都有相同的连接,就不会有任何问题。例如,我的所有模型只有一个连接
\ActiveRecord\Config::initialize(function ($cfg) use ($hostname, $username, $password, $database, $port) {
$cfg->set_model_directory('/src/Entity');
$cfg->set_connections(
array(
'development' => 'mysql://' . $username . ':' . $password . '@' . $hostname . '/' . $database
)
);
});
如果你有一些内部验证等你可以抛出\Exception 或从你的闭包中返回 false 并且事务将被回滚
YourModel::transaction(function()
{
YourModel::create(array("name" => "blah"));
throw new Exception("rollback!");
});
YourModel::transaction(function()
{
YourModel::create(array("name" => "blah"));
return false; # rollback!
});
您还可以像往常一样获取连接实例并开始您的交易
$user = User::find_by_id($id);
$item = new Item();
$connection = ConnectionManager::get_connection();
$connection->transaction();
try{
//Do stuff with the items...
$user->name = 'somename';
$user->save();
$item->quantity = 0;
$item->save();
$connection->commit();
}
catch (\Exception $exception){
throw $exception;
$connection->rollback();
}
ps:这里也有一些例子http://www.phpactiverecord.org/docs/ActiveRecord/Model#methodtransaction
关于php - 使用模型时如何在 PHP Active Record 中创建事务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24679392/