如何优雅地管理Kohana / PHP中的数据库事务

时间:2012-02-13 03:24:14

标签: php database transactions kohana kohana-orm

我是Kohana的新手,但来自Spring / Java背景。

在Spring中,我习惯了所有自动应用DB事务的服务方法。我只是标记方法以指示它是否只需要读取事务或读/写。

在Kohana,人们在这方面做了什么?我正在使用的新应用程序没有交易,除了在他们知道有必要的几个地方手动。对我来说这似乎有点风险,很容易忽略一些事务一致性要求,总是很高兴在Spring中全局强制执行。

4 个答案:

答案 0 :(得分:4)

在Kohana中,交易需要手动完成,没有办法像Spring一样 您可以在下面找到解决问题的方法:
使用Database方法:

$db = Database::instance();
$db->begin();

try
{
    // do your stuff here

    $db->commit();
}
catch(Database_Exception $e)
{
    $db->rollback();
}

使用查询生成器:

DB::query('START TRANSACTION');
// do your stuff here

If (no errors)
    DB::query('COMMIT');
else
    DB::query('ROLLBACK');

答案 1 :(得分:2)

我创建了一个Kohana模块(受Spring启发),使得使用事务变得更加容易:

https://github.com/brazzy/kohana-transactional

添加模块后,您只需添加

即可
public $_transactional = true;

到控制器,并且所有操作都在事务内自动执行,当事件因异常而失败时回滚。在我看来,这是最有用的实现,因为在PHP项目中似乎没有单独的服务层。

我最终可能会实现对只读事务的支持(如果可以以独立于供应商的方式进行)。

答案 2 :(得分:1)

以下是我如何处理它:

  1. 为所有服务方法类创建基类:

    abstract class Base
    {
    
        public function __call($method,$arguments)
        {
                // Start transaction here
                echo 'start';
    
                try
                {                    
                    call_user_func_array(array($this, $method), $arguments);
    
                    // Commit
                    echo ' commit';
                }
                catch ($e)
                {
                    // Roll back
                }                       
        }
    
    }
    
  2. 创建一个包含所有“受保护”功能的子类:

    class Member extends Base
    {
            protected function test()
            {
                echo 'test';
            }
    }
    
  3. 致电服务方式:

    $member = new Member();
    
    $member->test();
    
  4. 将显示:“start test commit”

    这里的诀窍是你必须对你的所有函数使用“protected”,否则它将不再运行(它将直接调用“test”函数,而不是通过__call()。

答案 3 :(得分:1)

手动完成并针对您的个人情况:

$db = Database::instance();
$db->begin();
try{
    // do your stuff
    $db->commit();
}catch(ORM_Validation_Exception $e){
    // ceep care WHAT you catch
    $db->rollback();
}catch(Exception $e){
    // and catch whatever exceptions too
    // or your rollback is blown in the wind
    $db->rollback();
    throw $e;
}