私の目標は、デッドロックが見つかった場合に InnoDB トランザクションを正しい方法で再起動することです。実行時にオブジェクトのデータが変更される場合があり、以前の状態にロールバックする必要があります。そのために Object Cloning を使用するかもしれませんが、これらのオブジェクトには__clone()
メソッドが定義されておらず、それらを追加する時間がないため、100% 確実ではありません。反対側から見ると、これらのオブジェクトが内部でオブジェクトを構成していることは非常にまれです。
これが私のコードです:
protected function callAction() {
$action = $this->Method.'Action';
// Storing an Object
$SavedPackageObject = clone $this->PackageObject;
try {
// First attempt
$res = $this->PackageObject->$action();
} catch(MySQLiDeadlockException $e) {
$i = 0;
do {
// Restoring an Object
$this->PackageObject = clone $SavedPackageObject;
try {
$res = $this->PackageObject->$action();
// Success
break;
} catch(MySQLiDeadlockException $e) {
// Cancel iterations if limit is reached
if($i > 9)
throw $e;
usleep(100000);
$i++;
}
} while(1);
}
return $res;
}
オブジェクトのコピーには、ディープ クローニングという別のアプローチがあります。
unserialize(serialize($Object));
__clone()
また、これらすべてのパッケージ オブジェクトの親クラスに追加することも考えています。
// php.net example
function __clone(){
foreach($this as $name => $value){
if(gettype($value)=='object'){
$this->$name= clone($this->$name);
}
}
}
質問:親で使用clone
および定義__clone()
しても問題ありませんか、それとも単にシリアル化/非シリアル化できますか?