PHP - 具有命令模式的文件系统库

时间:2014-04-10 17:51:16

标签: php transactions filesystems distributed-transactions

我正在寻找一个实现命令模式的文件系统库,因此我可以撤消在文件系统中所做的更改,例如通过数据库错误,我可以轻松地以原始方式保护数据完整性(可能具有悲观锁定)。 ..

你知道这样一个系统,还是我必须自己实现呢?

这个例子有点虚拟,因为我们通常会用文件替换来做,我们会把文件名保存在数据库中。请稍等一下......

示例:

try {
    $delete = $file1->delete();
    $create = $file2->create();
    $trans = $db->createTransaction(function () use ($db){
        $stmt = $db->prepare('UPDATE files SET name = :new_name WHERE name = :old_name');
        $stmt->execute(array(
            'old_name' => $file1->name,
            'new_name' => $file2->name
        ));
    });
    $trans->commit();
}
catch(Exception $e){
    if ($trans)
        $trans->rollback();
    if ($create)
        $create->undo();
    if ($delete)
        $delete->undo();
    throw $e;
}

OFC。我想自动处理回滚并检查文件锁定顺序(如果有锁)是否为abc以防止死锁。

例如,使用如下界面:

try {
    $commands = new Commands();
    $commands->add(new FileDeleteCommand($file1));
    $commands->add(new FileCreateCommand($file2));
    $commands->add(new DatabaseTransaction(
        function ($db) use ($file1, $file2){
            $stmt = $db->prepare('UPDATE files SET name = :new_name WHERE name = :old_name');
            $stmt->execute(array(
                'old_name' => $file1->name,
                'new_name' => $file2->name
            ));
        }
    ));
    $commands->execute();
}
catch(Exception $e){
    $commands->undo();
    throw $e;
}

这种方法存在局限性,例如我必须在最后一个地方提交事务,因为我已经提交时无法回滚它,但我可以忍受...

或替代界面:

try {
    $transactions = new DistributedTransaction();

    $transactions->add(new FileSystemTransaction(
        function () use ($file1, $file2){
            $file1->delete();
            $file2->create();
        }
    ));

    $transactions->add(new DatabaseTransaction(
        function ($db) use ($file1, $file2){
            $stmt = $db->prepare('UPDATE files SET name = :new_name WHERE name = :old_name');
            $stmt->execute(array(
                'old_name' => $file1->name,
                'new_name' => $file2->name
            ));
        }
    ));
    $transactions->commit();
}
catch(Exception $e){
    $transactions->rollback();
    throw $e;
}

问题是我们如何一次提交2笔交易?我认为我们实现其中之一的唯一方法是:文件系统事务,但我愿意接受建议......

我添加了一个新标记,我认为这是一个简单的distributed transaction问题,它包含数据库事务资源和文件系统事务资源。

1 个答案:

答案 0 :(得分:0)

我在PHP中没有找到类似的东西,所以我开始自己的php-transactions项目来填补空白。

它将实现具有有限功能的分布式事务和文件系统事务。我打算为协作式多任务添加一些支持,因为当它们相互依赖时,将文件系统和数据库事务分开会更容易。它也适用于承诺和发电机。我想我将在2014年6月底之前完成1.0。