我理解事务如何工作,一切都按预期运行,但我不喜欢访问提交或回滚事务的连接方式。
我有3个服务类可以访问同一个单例连接对象。我想在一个事务中包装这三件事,所以我这样做:
try {
$service1 = new ServiceOne;
$service2 = new ServiceTwo;
$service3 = new ServiceThree;
$service1->insertRec1($data);
$service2->deleteRec2($data);
$service3->updateRec3($data);
$service1->getSingletonConnection()->commit();
}
catch(Exception $ex) {
$service1->getSingletonConnection()->rollback();
}
getSingletonConnection返回的连接对象只是oci8连接的包装器,提交是oci_commit
;回滚是oci_rollback
。
正如我所说,这是有效的,因为它们都访问相同的连接,但通过任意服务对象访问连接感觉不对。此外,我的应用程序中使用了两个不同的数据库,因此我需要确保检索并提交正确的数据库...不确定是否有任何解决方法。
有没有更好的方法来处理交易?
答案 0 :(得分:2)
访问它感觉不对 任意连接 服务对象。
我100%同意你的意见。
在我看来,如果每个服务只构成数据库事务的一部分,那么该服务不能直接负责确定要使用的数据库会话。您应该在定义事务的代码级别选择和管理连接。
因此,您当前的代码将被修改为:
try {
$conn = getSingletonConnection();
$service1 = new ServiceOne($conn);
$service2 = new ServiceTwo($conn);
$service3 = new ServiceThree($conn);
$service1->insertRec1($data);
$service2->deleteRec2($data);
$service3->updateRec3($data);
$conn->commit();
}
catch(Exception $ex) {
$conn->rollback();
}
这似乎可以简化处理您的双数据库问题,因为只有一个地方可以决定使用哪个连接,并且您将直接引用该连接,直到您结束事务。
如果您想从单例连接扩展到连接池,这是我能想到的唯一方法,以保证所有三个服务调用都使用相同的连接。
答案 1 :(得分:1)
单一连接没有任何内在错误。 如果您有多个连接,则每个连接都运行一个独立的事务。你基本上有两个选择。
作为一种绕过您要连接的两个独立数据库实例的方法:使用数据库链接以便您只连接到单个数据库