diff --git a/lib/Cake/Model/Datasource/Database/Mysql.php b/lib/Cake/Model/Datasource/Database/Mysql.php index b94ece767d4..70c51366c3f 100644 --- a/lib/Cake/Model/Datasource/Database/Mysql.php +++ b/lib/Cake/Model/Datasource/Database/Mysql.php @@ -682,7 +682,7 @@ public function getSchemaName() { * @return boolean */ public function supportNestedTransaction() { - return version_compare($this->getVersion(), '4.1', '>='); + return $this->nestedTransaction && version_compare($this->getVersion(), '4.1', '>='); } } diff --git a/lib/Cake/Model/Datasource/Database/Postgres.php b/lib/Cake/Model/Datasource/Database/Postgres.php index 261a06d6cf0..35f568aad85 100644 --- a/lib/Cake/Model/Datasource/Database/Postgres.php +++ b/lib/Cake/Model/Datasource/Database/Postgres.php @@ -901,7 +901,7 @@ public function getSchemaName() { * @return boolean */ public function supportNestedTransaction() { - return version_compare($this->getVersion(), '8.0', '>='); + return $this->nestedTransaction && version_compare($this->getVersion(), '8.0', '>='); } } diff --git a/lib/Cake/Model/Datasource/Database/Sqlite.php b/lib/Cake/Model/Datasource/Database/Sqlite.php index cbc2caeaac7..419709892d8 100644 --- a/lib/Cake/Model/Datasource/Database/Sqlite.php +++ b/lib/Cake/Model/Datasource/Database/Sqlite.php @@ -565,7 +565,7 @@ public function getSchemaName() { * @return boolean */ public function supportNestedTransaction() { - return version_compare($this->getVersion(), '3.6.8', '>='); + return $this->nestedTransaction && version_compare($this->getVersion(), '3.6.8', '>='); } } diff --git a/lib/Cake/Model/Datasource/DboSource.php b/lib/Cake/Model/Datasource/DboSource.php index 6c7f37a4742..a37709df9d8 100644 --- a/lib/Cake/Model/Datasource/DboSource.php +++ b/lib/Cake/Model/Datasource/DboSource.php @@ -69,6 +69,15 @@ class DboSource extends DataSource { */ public $cacheMethods = true; +/** + * Flag to support nested transactions. If it is set to false, you will be able to use + * the transaction methods (begin/commit/rollback), but just the global transaction will + * be executed. + * + * @var boolean + */ + public $nestedTransaction = true; + /** * Print full query debug info? * diff --git a/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php b/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php index 5a2cd8549df..647c373c40d 100644 --- a/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php @@ -54,7 +54,7 @@ public function setConnection($conn) { } public function supportNestedTransaction() { - return self::$nested; + return $this->nestedTransaction && self::$nested; } } @@ -879,6 +879,30 @@ public function testTransactionNested() { * @return void */ public function testTransactionNestedWithoutSupport() { + $conn = $this->getMock('MockPDO'); + $db = new DboTestSource(); + $db->setConnection($conn); + $db->nestedTransaction = false; + DboTestSource::$nested = true; + + $conn->expects($this->once())->method('beginTransaction')->will($this->returnValue(true)); + $conn->expects($this->never())->method('exec'); + $conn->expects($this->once())->method('commit')->will($this->returnValue(true)); + + $db->begin(); + $db->begin(); + $db->commit(); + $db->begin(); + $db->rollback(); + $db->commit(); + } + +/** + * Test nested transaction disabled + * + * @return void + */ + public function testTransactionNestedDisabled() { $conn = $this->getMock('MockPDO'); $db = new DboTestSource(); $db->setConnection($conn);