我真的很喜欢这个**NestedPDO**Yii解决方案,但我需要一些不同的事务处理。
我希望仅在所有嵌套事务都可以提交时才提交嵌套事务,并且如果一个事务执行了回滚,则所有事务都应回滚。
我怎么能那样做呢?
我尝试更改回滚功能,但没有成功:
public function rollBack() {
$this->transLevel--;
if($this->transLevel == 0 || !$this->nestable()) {
parent::rollBack();
} else {
$level = $this->transLevel;
for($level; $level>1; $level--){
$this->exec("ROLLBACK TO SAVEPOINT LEVEL{$this->constantlevel}");
}
//parent::rollBack();
}
}
我在考虑修改NestedPDO:在函数commit()中只对最外层的事务进行提交,而在函数rollBack()中则回滚到最外层的事务,不管是哪个子事务导致了回滚。但是我无法完成...
我正在使用MySQL和InnoDB表,我不确定自动提交是否有效,但在事务中回显自动提交的值时,我总是得到值1,这意味着自动提交已启用,但在事务中,自动提交应设置为0。我不确定这是否是整个回滚不起作用的原因?
3条答案
按热度按时间i34xakig1#
If you want the whole transaction be rolled back automatically as soon as an error occurs, you could just re-throw the exception from
B
's exception handler when called from some specific locations (eg. fromA()
):Now I understand you actually just want your wrapper to detect if a transaction is already in progress, and in this case not start the transaction.
Therefore you do not really need the
NestedPDO
class. You could create a class like this instead:vwoqyblh2#
根据@RandomSeed的回答,我创建了一个默认Yii交易处理的'drop in':
这是我的SingleTransactionManager类:
此类“ Package ”主数据库连接,应在配置中将其声明为组件,如下所示:
请注意,
dbConnection
属性应该是master数据库联机的表示式。现在,当巢状Try catch区块中的巢状交易时,您可以在例如巢状交易3中建立错误,而1和2上的巢状交易也会回复。测试代码:
产生以下输出:
ryevplcw3#
恕我直言,在应用程序代码中模拟“嵌套事务”的想法是一种反模式。在应用程序中有许多不可能解决的异常情况(请参阅我对https://stackoverflow.com/a/319939/20860的回答)。
在PHP中,最好保持简单。工作被自然地组织成请求,所以使用请求作为事务作用域。
忘记所有关于事务级别的废话,模型不应该启动、提交或回滚任何事务。