in questa maniera però, provando lato controller a inserire valori manualmente, ad esempio, valori testuali in campi int, la transazione avviene ugualmente, lasciando vuoto il campo int nel db perchè permette valori null.
nel caso,ad esempio, io inserisca valori numerici che violino una foreign key… a quel punto vedo l’errore.
la domanda è. non c’è un modo che la transazione passi prima la validazione yii e poi anche i vincoli del db. ora va solo per la seconda questione, e il db nel caso arrivino caratteri al posto di un int non genera un’eccezione ma lascia il campo vuoto.
Già fatto, ma purtroppo non agisce come dovrebbe. Oggi ero un pò bollito quando stavo scrivendo questo codice, quindi mi sono ripromesso di riguardarlo domani mattina con calma.
Voi avete mai provato qualcosa di simile, io voglio che 3-4 blocchi di istruzioni vadano tutti a buon fine altrimenti rollback!
purtroppo, per il codice che ho testato io, questo non riuscivo a farlo.
Anche togliendo i false, alcuni model venivano salvati correttamente nonostane alcune istruzioni dopo non andavano a buon fine.
Il codice che ho postato è di esempio,trovato a giro, domani se dovessi continuare ad avere problemi, vi posto il mio. Intanto se avete casi d’uso simili o consigli, vi ringrazio!
oltretutto seguendo il consiglio di sensorario avresti perso del tutto ogni vantaggio datoti da active record.
ad ogni modo per rendere il codice più chiaro io lo modificherei leggermente rendendolo così:
$transaction = Yii::app()->db->beginTransaction();
try {
$user = new User();
$user->username = $form->username;
$user->password = $form->password;
$user_save = $user->save();
$user_info = new UserInfo();
$user_info->name = $form->name;
$user_info->user = $user->id;
$user_info->age = $form->age;
if(!$user_save || !$user_info->save()){
throw new Exception('could not save on db');
$transaction->commit();
} catch(Exception $e) {
$transaction->rollBack();
}
in questa maniera hai un solo commit ed un solo rollback rendendolo più leggibile.
poi volendo essere pignoli potresti wrappare tutta sta roba in un servizio in maniera tale che il controller faccia giustamente solo il suo lavoro di passacarte