Reputation: 63626
try
{
$con->beginTransaction();
$this->doSave($con);
$con->commit();
}
catch (Exception $e)
{
$con->rollBack();
throw $e;
}
The code above is quite standard an approach to deal with transactions,
but my question is:what if $con->rollBack()
also fails?
It may cause db lock,right?If so,what's the perfect way to go?
Upvotes: 2
Views: 4694
Reputation: 13461
MySQL handles an error situation by rolling back the transaction itself.
Rolling back can be a slow operation that may occur implicitly without the user having explicitly asked for it (for example, when an error occurs).
The MySQL documentation covers your "what if case"
If a session that has autocommit disabled ends without explicitly committing the final transaction, MySQL rolls back that transaction.
Further:
Both commit and rollback release all InnoDB locks that were set during the current transaction.
Edit: I set up a test for your proposed situation. Using an innoDB table with MySQL 5.
$db = new DB();
$db->beginTransaction();
$db->exec("INSERT INTO `table` (`val`) VALUES('commit?')");
sleep(30);
$db->commit();
This works as I've described below in the comments. If allowed to complete, the transaction is committed to the table after 30 seconds.
If I kill the script before allowing it to complete, the transactions is rolled back and the table is left in a clean state - as expected.
Upvotes: 1
Reputation: 400912
When using transactions, the basic idea is that nothing will actually get permanently written to the database until commit
is called.
A couple of situations :
die
)rollback
.
To makes things simple : starting from the begin transaction
, nothing gets permanently written to the database, until you send a commit
. If there is no commit... Nothing is permanently written, and when your PHP script disconnects from the DB, the DB "cancels" what that PHP script did not commit.
Of course, this is exactly the same if you are using something else than PHP to connect to your database -- like the command-line MySQL client, for instance.
Upvotes: 5
Reputation: 338
Use a transactional database engine, such as InnoDB. This will guarantee data integrity in the event of a query failure during a write. MySQL defaults to using the MyISAM engine, which is faster and is not transactional. All you need to do is change the storage engine when creating your database.
Upvotes: 0