Doctrine Transaction Unexpected Nesting Level Increasing

#作業環境
PHP5.3 + Fuel 1.8.1 + Doctrine

#問題
業務上、1つのトランザクションの中に、下記のPseudoコードの感じで処理を実行し、最後纏めてコミットしたい。

~~~
$em = \Fuel\Doctrine::manager("default");
$em->getConnection()->beginTransaction();
…
DB登録処理呼び出し関数1($em);
DBクエリ処理呼び出し関数1($em);
繰り返し処理{
…
　　　　DB登録処理呼び出し関数2($em);
　　　　DB更新処理呼び出し関数1($em);
…
}
…
DB更新処理呼び出し関数2($em);
$em->commit();
~~~

が、コミットはどうしても成功せず、３日を悩まされました。

#調査経過
たまたま、Doctrineトランザクション管理のNestingレベルを見ようとして、
Doctrineトランザクション公式参照⇒[https://www.doctrine-project...](https://www.doctrine-project.org/projects/doctrine-dbal/en/2.9/reference/transactions.html)

⇓をDB変更や登録関数の実行前後に貼って、驚きの結果がわかりました。
`echo "TransactionNestingLevel Before Insert :".$em->getConnection()->getTransactionNestingLevel()."\n";`

__繰り返し処理の中で、Nestingレベルの数値がどんどん上がる！！！__

~~~
TransactionNestingLevel Before Insert :11
TransactionNestingLevel After Insert :11
TransactionNestingLevel Before Insert :41
TransactionNestingLevel After Insert :41
TransactionNestingLevel Before Insert :215
TransactionNestingLevel After Insert :215
TransactionNestingLevel Before Insert :301
TransactionNestingLevel After Insert :301
TransactionNestingLevel Before Insert :345
TransactionNestingLevel After Insert :345
TransactionNestingLevel Before Insert :395
TransactionNestingLevel After Insert :395
TransactionNestingLevel Before Insert :461
TransactionNestingLevel After Insert :461
~~~
__Are you kidding me！！__![なんじゃと](https://img5.duitang.com/uploads/item/201407/22/20140722111618_dhnsB.thumb.700_0.jpeg "なんじゃと")

トランザクション階層が461階層に⇓

~~~
トランザクション階層1
    トランザクション階層2
        トランザクション階層3
                    …
                                        トランザクション階層461
~~~

変更をDBに反映するために、`$em->commit();`を__460__回実行せよ！！だからコミットできないか！
![なんじゃと](https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1555557905&di=6db1db1b6f595e02803f54ec8d304b04&imgtype=jpg&er=1&src=http%3A%2F%2Fimg2.downza.cn%2Fandroid%2Fyingyong%2Fzxyd-582%2F2016-03-14%2F14981f240ddadfc588b6e83731435175.jpg "なんじゃと")

待って！今回操作対象データが230件。最後に461件というのは、230の2倍がプラスされたんじゃないか？都合がいい数値に手がかりがありそう！！

いろいろ実験を経て、下記の感じのコードを実行すると、不具合の箇所が特定できました。

~~~
$em = \Fuel\Doctrine::manager("default");
$em->getConnection()->beginTransaction();
echo "TransactionNestingLevel beginTransaction:".$em->getConnection()->getTransactionNestingLevel()."\n";
$info = array();
$info[0] = array(
    "Sequence"=>5
    …
);
$info[1] = array(
    "Sequence"=>6
    …
);
echo "TransactionNestingLevel After Setting array :".$em->getConnection()->getTransactionNestingLevel()."\n";
~~~

結果：

~~~
TransactionNestingLevel beginTransaction :1
TransactionNestingLevel After Setting array :3
~~~

#結論

__配列代入処理が一回実行で、DoctrineのトランザクションNestingレベルが1 Plusされる__ことが分かりました。だからか！前230件の2倍Plusされるのも、登録関数が呼ばれる前に、データを配列で渡すために、配列代入処理を2回実施しましたからです。

__わけわからねぇ！！！！！__

![なんじゃと](https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1554961619319&di=5ef76d00e58f943aedbd5dd66030f163&imgtype=0&src=http%3A%2F%2Fimg5.duitang.com%2Fuploads%2Fitem%2F201510%2F13%2F20151013154235_jX53Q.thumb.700_0.jpeg "なんじゃと")

#対策
はい！退避策として、繰り返し処理の中のDB変更処理を全部外に出して、`$em->getConnection()->setAutoCommit(false);`で、繰り返し処理でPlusされたトランザクションレベルを1に戻した。

~~~
$em = \Fuel\Doctrine::manager("default");
$em->getConnection()->beginTransaction();
…
DB登録処理呼び出し関数1($em);
DBクエリ処理呼び出し関数1($em);
繰り返し処理{
…
…
}
…
$em->getConnection()->setAutoCommit(false);
DB登録処理呼び出し関数2($em);
DB更新処理呼び出し関数1($em);
…
DB更新処理呼び出し関数2($em);
$em->commit();
~~~

こんなつまらないことで、3日間が蒸発した！！！
![死ね](http://s11.sinaimg.cn/mw690/002c8tVLzy78DbwbipI8a&690 "死ね")