Fixed issue where Model::saveAll() would incorrectly commit a transaction which was not started in that function call itself.

This commit is contained in:
ADmad 2010-11-03 18:55:42 +05:30
parent 268dae722e
commit eb76ab95f2
3 changed files with 44 additions and 9 deletions
cake
libs/model
tests/cases/libs/model

View file

@ -559,9 +559,9 @@ class Model extends Overloadable {
* *
* Example: Turn off the associated Model Support request, * Example: Turn off the associated Model Support request,
* to temporarily lighten the User model: * to temporarily lighten the User model:
* *
* `$this->User->unbindModel( array('hasMany' => array('Supportrequest')) );` * `$this->User->unbindModel( array('hasMany' => array('Supportrequest')) );`
* *
* unbound models that are not made permanent will reset with the next call to Model::find() * unbound models that are not made permanent will reset with the next call to Model::find()
* *
* @param array $params Set of bindings to unbind (indexed by binding type) * @param array $params Set of bindings to unbind (indexed by binding type)
@ -1589,7 +1589,7 @@ class Model extends Overloadable {
} }
if ($options['atomic'] && $options['validate'] !== 'only') { if ($options['atomic'] && $options['validate'] !== 'only') {
$db->begin($this); $transactionBegun = $db->begin($this);
} }
if (Set::numeric(array_keys($data))) { if (Set::numeric(array_keys($data))) {
@ -1629,8 +1629,12 @@ class Model extends Overloadable {
break; break;
default: default:
if ($options['atomic']) { if ($options['atomic']) {
if ($validates && ($db->commit($this) !== false)) { if ($validates) {
return true; if ($transactionBegun) {
return $db->commit($this) !== false;
} else {
return true;
}
} }
$db->rollback($this); $db->rollback($this);
return false; return false;
@ -1740,7 +1744,11 @@ class Model extends Overloadable {
default: default:
if ($options['atomic']) { if ($options['atomic']) {
if ($validates) { if ($validates) {
return ($db->commit($this) !== false); if ($transactionBegun) {
return $db->commit($this) !== false;
} else {
return true;
}
} else { } else {
$db->rollback($this); $db->rollback($this);
} }

View file

@ -3121,6 +3121,22 @@ class ModelWriteTest extends BaseModelTest {
$Post->saveAll($data); $Post->saveAll($data);
} }
/**
* test saveAll with nested saveAll call.
*
* @return void
*/
function testSaveAllNestedSaveAll() {
$this->loadFixtures('Sample');
$TransactionTestModel =& new TransactionTestModel();
$data = array(
array('apple_id' => 1, 'name' => 'sample5'),
);
$this->assertTrue($TransactionTestModel->saveAll($data, array('atomic' => true)));
}
/** /**
* testSaveAllTransaction method * testSaveAllTransaction method
* *

View file

@ -290,7 +290,7 @@ class Article extends CakeTestModel {
*/ */
class BeforeDeleteComment extends CakeTestModel { class BeforeDeleteComment extends CakeTestModel {
var $name = 'BeforeDeleteComment'; var $name = 'BeforeDeleteComment';
var $useTable = 'comments'; var $useTable = 'comments';
function beforeDelete($cascade = true) { function beforeDelete($cascade = true) {
@ -3557,6 +3557,7 @@ class FruitNoWith extends CakeTestModel {
) )
); );
} }
class UuidTagNoWith extends CakeTestModel { class UuidTagNoWith extends CakeTestModel {
var $name = 'UuidTag'; var $name = 'UuidTag';
var $useTable = 'uuid_tags'; var $useTable = 'uuid_tags';
@ -3573,11 +3574,21 @@ class UuidTagNoWith extends CakeTestModel {
class ProductUpdateAll extends CakeTestModel { class ProductUpdateAll extends CakeTestModel {
var $name = 'ProductUpdateAll'; var $name = 'ProductUpdateAll';
var $useTable = 'product_update_all'; var $useTable = 'product_update_all';
} }
class GroupUpdateAll extends CakeTestModel { class GroupUpdateAll extends CakeTestModel {
var $name = 'GroupUpdateAll'; var $name = 'GroupUpdateAll';
var $useTable = 'group_update_all'; var $useTable = 'group_update_all';
} }
class TransactionTestModel extends CakeTestModel {
var $name = 'TransactionTestModel';
var $useTable = 'samples';
function afterSave($created) {
$data = array(
array('apple_id' => 1, 'name' => 'sample6'),
);
$this->saveAll($data, array('atomic' => true, 'callbacks' => false));
}
}