Transactions
Use transactions in FuzzyRecord to prevent bad things happening to your data when something goes wrong.
FuzzyRecord can rollback your database when bad things do happen. It also removes bad objects from the in-memory cache and / or Memcache store if you are using them.
In MySQL, you must use the InnoDB table format rather than the default MyISAM table format, or transactions will always appear to succeed.
FuzzyRecord supports transactions in two ways:
1) Explicit Transactions
If you are updating multiple objects as part of a complex action, you can explicitly wrap the action in a transaction, and rollback the state of the data if something goes wrong.
A contrived example:
DB::start_transaction();
$user = new User();
$user->first_name = $_POST["first_name"];
$user->last_name = $_POST["last_name"];
$user->email = $_POST["email"];
$user->save();
$account = new Account();
$account->user = $user;
$account->date_opened = now();
$account->save();
//Perform some other action that might fail
$card_status = process_card_details($account->id,$card_details);
if ($card_status != "accepted") {
DB::rollback();
header("Location: /Card_declined");
exit;
}
$account->status = "active";
$account->save();
DB::commit();
In this example, when something outside of our control happened, we rolled back the state of the data we just modified to where it was before our transaction started.
Automatic rollback
If something goes wrong that FuzzyRecord knows about, it will rollback automatically.
DB::start_transaction();
$user = new User();
$user->first_name = $_POST["first_name"];
$user->last_name = $_POST["last_name"];
$user->email = $_POST["email"];
$user->save();
// Users don"t (generally) have any fur,
// and our user model doesn't have a fur_type property.
// Will generate an exception, and rollback the data
$user = User::find_by_fur_type("extra fluffy");
// We"ll never get here unless we caught the exception,
// and even then the data will be in its previous state
DB::commit();
2) Automatic Transactions
FuzzyRecord automatically wraps create, update and delete model calls in a transaction, if one isn’t already in progress.
$invalid_user = new User();
$invalid_user->first_name = $_POST["first_name"];
$invalid_user->last_name = $_POST["last_name"];
$invalid_user->email = "Not an email address";
$account = new Account();
$account->user = $user;
$account->date_opened = now();
// Will fail, even though $account is valid,
// because a dependent object that needed to be written was invalid ($user)
$account->save();