2012-02-13 37 views
2

我是Kohana的新手,但来自Spring/Java背景。如何在Kohana/PHP中优雅地管理数据库事务

在春天,我习惯了所有自动应用数据库事务的服务方法。我只是标记方法来指示它是否只需要读事务或读/写。

在Kohana,人们在这方面做了什么?我正在使用的新应用没有交易,只有在他们知道必要的地方手动完成。对我来说,这看起来有点冒险,很容易忽略一些事务一致性要求,在Spring中全局执行它总是很好的。

+0

那么你的Kohana的文件说一下吗?据我所知,它是一个codeigniter框架的分支,所以你可以检查codeigniter的文档,如果它的任何帮助。 – linuxeasy 2012-02-13 06:49:29

+0

Kohana不这样做。它应该,但我认为。 – 2012-02-29 07:25:28

回答

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(); 
    

它会显示: “开始测试提交”

这里的诀窍是你将不得不使用“pro检查“所有的功能,如果不是,它将不再运行(它将直接调用”测试“功能,而不是通过__call()。

+0

儿子,你提出的一个很好的解决方案,就像你在这里一样处理同样的问题。 :)但有一点,春季交易允许我们将它们设置为只读或读/写(例如对于innodb表有用)。我可能会提出一个命名方案,例如[functioname_RW]来指示txn是应该以只读模式还是读写模式启动。 – 2012-03-02 03:49:48

+1

请注意,当服务方法调用die或exit时,此解决方案将失败 - 您需要注册一个关闭函数来处理这种情况。 – 2012-04-08 16:22:23

3

在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'); 
+0

如果PHP有'最后',这可以写得更优雅。 – shadowhand 2012-02-14 02:09:35

2

我创建了一个Kohana的模块(由Spring启发),使得使用事务轻松了不少:

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

添加模块后,只需将它添加

public $_transactional = true; 

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

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

0

手和你个人的情况下就做:

$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; 
} 
相关问题