gpt4 book ai didi

mysql - 嵌套事务的总回滚

转载 作者:行者123 更新时间:2023-11-29 03:38:55 31 4
gpt4 key购买 nike

我真的很喜欢这个 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. 我不确定这是否是整个回滚对我不起作用的原因?

最佳答案

<罢工>如果您希望在发生错误时立即自动回滚整个事务,您可以重新抛出 B 中的异常。从某些特定位置调用时的异常处理程序(例如来自 A() ):

function A(){
...
$this->B(true);
...
}

/*
* @param B boolean Throw an exception if the transaction is rolled back
*/
function B($rethrow) {
$transaction=Yii::app()->db->beginTransaction();
try {
//do something
$transaction->commit();
} catch(Exception $e) {
$transaction->rollBack();
if ($rethrow) throw $e;
}
}

<罢工>

现在我明白了,您实际上只是想让包装器检测交易是否已经在进行中,并且在这种情况下不启动交易。

因此你并不真的需要 NestedPDO类(class)。您可以改为创建这样的类:

class SingleTransactionManager extends PDO {
private $nestingDepth = 0;

public function beginTransaction() {
if(!$this->nestingDepth++ == 0) {
parent::beginTransaction();
} // else do nothing
}
public function commit() {
$this->nestingDepth--;
if (--$this->nestingDepth == 0) {
parent::commit();
} // else do nothing
}

public function rollback() {
parent::rollback();
if (--$this->nestingDepth > 0) {
$this->nestingDepth = 0;
throw new Exception(); // so as to interrupt outer the transaction ASAP, which has become pointless
}

}
}

关于mysql - 嵌套事务的总回滚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17062538/

31 4 0