Reputation: 8575
I have some (php) code that performs critical updates on an InnoDB table.
I'm using (SELECT ... FOR UPDATE), so I need to be inside a transaction.
This code is being executed when data is posted from a form, and I have a message system in place so that error/success messages are stored in a database, and extracted from the database next time a page is rendered.
Some pseudocode: (I'm ommitting stuff like the try/catch blocks and escaping that I have in my real code)
beginTransaction();
query("SELECT * FROM `table` WHERE id=1 FOR UPDATE");
$x=$_POST[$x];
query("UPDATE `table` SET `field` = $X");
//add other data in the db related to $X
query("INSERT INTO `othertable` (x,y,x) VALUES (......)");
//check for various errors...
$erros=0
if ($error_condition_1) {
messageSystem("Error Condition 1!")
$errors+=1;
}
if ($error_condition_2) {
messageSystem("Error Condition 2!")
$errors+=1;
}
if ($errors) {
rollBackTransaction();
} else {
commitTransaction();
}
The problem should be obvious: when messageSystem stores the error in the database the changes will be rolled back later, and the user will never see the error messages.
There are two easy solutions I can see:
messageSystem
is called outside the transaction. However it is more readable and quicker to write if I can do it inline like the above. Also, what if this is library code that may already be inside a nested transaction?messageSystem
so that it uses its own connection to the database. But then what if I make messageSystem more complicated, and decide that it needs to lock an entry in the session
table before it adds messages to that session. This could lead to a deadlock if my main code has also locked the session for some reason.And so my question: Is there any way to commit X when inside a (possibly nested) transaction such that if the transaction is rolled back, X will be committed anyway.
Alternatively is there any good way of avoiding the problem I've described.
Thanks!
Upvotes: 3
Views: 406
Reputation: 791
The simple answer is to use a second database connection for your error logging.
Upvotes: 2