Использование транзакций в CakePHP 2.1.3

Я использую базу данных на основе innoDB. Как я могу использовать транзакцию для сохранения данных.

У меня есть группа пользователей. Но сохраняет только последнюю запись в базе данных. Я не могу использовать saveAll, потому что мне нужно сохранить данные в нескольких таблицах, и все они взаимосвязаны.

Я даже не могу определить модель ассоциации-корабля, потому что в моей базе данных огромное количество записей. Таким образом, каждый раз соединение будет выполняться.

Пожалуйста, предложите, как я могу использовать концепцию транзакции?


person Arun Jain    schedule 03.07.2012    source источник


Ответы (1)


Все транзакции выполняются с текущим объектом DataSource.

Во-первых, вам нужно получить его (в модели):

$dataSrc = $this->getDataSource();

Этот метод возвращает объект DataSource, который в данный момент привязан к модели.

Затем вы можете использовать методы объекта DataSource для запуска, фиксации или отката транзакции:

$dataSrc->begin();
//Do something 

if (/*Everything is nice?*/) {
    $dataSrc->commit();
} else {
    //Bad things have happened
    $dataSrc->rollback();
}

Конечно, вам придется реализовать свою собственную логику. Начиная с Cake 2.2, вы также можете выполнять настоящие вложенные транзакции. Согласно Википедии, "вложенная транзакция" это:

Вложенная транзакция возникает, когда новая транзакция запускается инструкцией, которая уже находится внутри существующей транзакции. Говорят, что новая транзакция вложена в существующую транзакцию, отсюда и термин. Вложенные транзакции реализуются по-разному в разных базах данных. Однако их объединяет то, что изменения не становятся видимыми для каких-либо несвязанных транзакций до тех пор, пока самая внешняя транзакция не будет зафиксирована. Это означает, что фиксация во внутренней транзакции не обязательно сохраняет обновления в базе данных.

Конечно, все это зависит от используемой вами базы данных. Механизм хранения транзакций MySQL InnoDB поддерживает транзакции.

И еще одно уточнение в ответ на этот комментарий:

Да, я использую $this->Model->saveAll($this->request->data, array('deep' => true) в своем контроллере. Это написано в цикле foreach. И только последняя запись foreach будет сохранен в базе данных», — Арун Джейн.

$this->Model->saveAll(); НЕ нужно запускать в цикле! Он будет управлять вещами для вас «автоматически». Уберите его из цикла. Кроме того, ваш вопрос касался транзакций, а не сохранения данных с помощью saveAll(). Model::saveAll() — это просто оболочка для saveMany() и saveAssociated() — он выберет, какой метод использовать, в зависимости от типа ассоциации модели.

Прочтите книгу о тортах, там все очень хорошо объяснено...

person Borislav Sabev    schedule 04.07.2012
comment
когда я пытаюсь использовать $dataSrc = $this->getDataSource(); выдает ошибку: использование неопределенного метода. - person Arun Jain; 05.07.2012
comment
Вы пытаетесь сделать это в другом месте, а не в Модели? Нет другого случая, чтобы вы получили ошибку use of undefined method. - person Borislav Sabev; 05.07.2012
comment
Да, я использую $this-›Model-›saveAll($this-›request-›data, array('deep' =› true) в своем контроллере. Это написано в цикле foreach. И только последняя запись foreach будет сохранен в базе данных. - person Arun Jain; 05.07.2012
comment
$this->Model->saveAll(); НЕ нужно запускать в цикле! Он будет управлять вещами для вас автоматически. Уберите его из цикла. Кроме того, ваш вопрос касался транзакций, а не сохранения данных с помощью saveAll(). Model::saveAll() — это просто оболочка для saveMany() и saveAssociated() — она выберите, какой метод использовать, в зависимости от типа ассоциации модели. Прочитайте Книгу о тортах, там все очень хорошо объяснено... - person Borislav Sabev; 05.07.2012
comment
Спасибо, я знаю, как использовать метод saveAll(). Но в моем случае мне нужно сохранить данные для нескольких пользователей, при этом количество записей необходимо сохранить в таблицах, связанных с пользователями. И в соответствии с некоторыми условиями эти ассоциации могут динамически меняться для каждого пользователя. - person Arun Jain; 06.07.2012
comment
Ну нельзя передать массив данных для всех пользователей сразу и иметь возможность его сохранить. Вы должны передать массив соответствующим образом для каждого пользователя. Если вы хотите изменить ассоциации модели на лету, вы должны использовать привязки модели, поскольку они являются динамическими и могут быть изменены в любое время с помощью $this->ModelName->bindModel(); и $this->ModelName->unbindModel();. - person Borislav Sabev; 06.07.2012