What happened if rollback table if there is no transaction? - php

It rare case may be but for some reason I need an outer try catch for a purpose. So I can't able to control individual transactions.
so I have just one outer catch statement.
catch(Exception $e) {
DB::rollback();
Log:error($e->getMessage());
}
But what happened if there is an error before any transactions hasn't initiated. Is rollback cause unexpected damage ?

You can call DB::transactionLevel() to get count:
catch(Exception $e) {
if (0 < DB::transactionLevel()) {
DB::rollback();
}
Log:error($e->getMessage());
}
Reference: Illuminate\Database\ConnectionInterface | Laravel API

ROLLBACK applies to a "transaction", not a "table". There could be multiple tables involved in a transaction, or there could even be no tables yet involved.
ROLLBACK is prepared to do anything needed, even including "nothing". Don't worry.

Related

PDO Transaction syntax with try catch

What is the syntax preferred while using PDO transaction and try catch and Why?
$dbh->beginTransaction();
try {
} catch (Exception $e) {
}
OR
try {
$dbh->beginTransaction();
} catch (Exception $e) {
}
The existent answers seem to suggest that since $dbh->beginTransaction() could throw a PDOException it should be in the same try block of the actual transaction code, but this means that the rollBack() code itself will be wrong, because it could invoke a rollBack() without there being a transaction, which could also throw another PDOException.
The right logical ordering of this is that you put the code you want executed in one transaction in one catch block after the transaction has been created. You could also check that the return of beginTransaction() is true before proceeding. You could even check that the database session is in a transaction before calling rollback().
if ($dbh->beginTransaction())
{
try
{
//your db code
$dbh->commit();
}
catch (Exception $ex)
{
if ($dbh->inTransaction())
{
$dbh->rollBack();
}
}
}
Keep in mind that you could still, at least in theory, get an exception from beginTransaction() and rollBack() so I would put this in a separate function and enclose the invocation in another try-catch block.
You could also bubble the exception you get up to catch it and log all Exceptions in one place. But remember that some exceptions could be data integrity errors such as duplicate keys or invalid foreign keys, which would not be a database fault as such, but most probably a bug in your code.
With this approach, the main thing to keep in mind here is that the two try-catch blocks have a slightly different purpose. The inner one is purely to ensure that multiple queries are executed and committed atomically in one transaction and if something happens they are rolled back. The external try-catch would be to detect erroneous situations and log it, or whatever you would want to do if you have a problem with your database.
try {
$dbh->beginTransaction();
} catch (Exception $e) {
}
Simply because an exception could be thrown as you attempt to begin the transaction.
Note that you can place another try catch block inside the initial try.
The second one usually makes most sense. Since you may not always know what will cause the transaction to fail, you would want the rollback (and possibly commit) logic available in the catch, so you'd want to put the beginTransaction() inside of the try.
In addition to the try/catch make sure you set the error mode attribute:
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
And if anything you should catch the PDOExecption just because you should not treat all exception in the same way.
try {
$dbh->beginTransaction();
//do stuff
$dbh->commit();
} catch (PDOException $e) {
$dbh->rollBack();
//...
throw $e;
}
But if you still want to catch other exception add more catch blocks:
try {
....
} catch (PDOException $e) {
//handle pdo exception
}catch (Exception $ex) {
//handle others differently
}

Pdo Error Catching Try/Catch

After looking into using try catch blocks for my Pdo statements is it really a benefit? Does this just slow your code down?
I believe that there should be a try catch around the connection command in case the database connection fails. But does there really need to be try catch around each pre prepared statement? These should never change and never really error out.
Any thoughts?
I'm using Php and MySql.
There is no benefit to this:
try {
// exec statement
// exec statement
}
catch (Exception $e) {
// do nothing
}
If you aren't going to do anything with the error and provide a reasonable solution, then you may as well let the exception bubble up to the application's main "something went wrong" error page.
But you may want to do this:
// begin transaction
try {
// exec statement
// exec statement
// commit transaction
}
catch (Exception $e) {
// rollback transaction
// handle error or rethrow $e;
}
And prepared statements can throw exceptions. Perhaps a unique key is violated, or a foreign key constraint is, etc.
But the main point is, you don't use exceptions to hide or silence errors. You use them to catch an error, process it intelligently, and continue on accordingly.

In MySQL is it best practice to wrap LOCK TABLES calls in a try catch?

When executing a "LOCK TABLES" is it wise to wrap the call in a try/catch to make sure the table gets unlocked in case of an exception?
In general it's a good idea to use try { } catch for operations that require undoing a previous operation in case of any errors; it's not limited to just database statements.
That said, when using databases, it's advisable to use a more granular locking mechanism such as the one that comes with transactional databases such as InnoDB. You would still use try { } catch, but in this manner:
// start a new transaction
$db->beginTransaction();
try {
// do stuff
// make the changes permament
$db->commit();
} catch (Exception $e) {
// roll back any changes you've made
$db->rollback();
throw $e;
}
The exact behaviour of conflict resolution is defined by the transaction isolation level, which can be changed to suit your needs.

MYSQL Autocommit when using multiple functions

Will try to make this as simple as possible. I'm using throw/catch with my functions. The function takes in a name a description, and an array of users. It adds the name and description to one table, then takes the array of users, and does a seperate function for adding them into a connector table. I set the function up to turn autocommit off until the last user is entered and then commit. The problem is that if one of the users fails to go in (due to a foreign key constraint), the transaction isn't backed out. Does the fact that I'm calling a seperate function "reset" the autocommit and cause it to not work as intended? Am I doing it wrong by putting the rollback in the Catch clause?
try
{
autocommit=0
run insert query
if query fails: throw error, rollback
else
for count of array
run another function (this function does more SQL and throws its own errors if it fails)
autocommit=1
}
catch
{
rollback, autocommit=1;
display error
}
Hopefully I haven't oversimplified the code. Any help would be appreciated.
$this->dbh->beginTransaction();
try {
// do stuff
$this->dbh->commit();
} catch (PDOException $e) {
$this->dbh->rollBack();
throw $e;
}

What causes a rollback failed error in mySQL?

I get the following error when I try to perform a rollback.
Rollback failed. There is no active transaction.
I searched for this issue and found a few suggestions that recommend disabling the autocommit setting. But I am unsure how to do this. Is there any other reason for the above error? I am using MYSQL and Zend and my php.ini file loaded the required drivers.
MySQL works in autocommit by default. You can turn it off with:
$connection->setAttribute(Doctrine_Core::ATTR_AUTOCOMMIT, false);
Another idea I have is you didn't start the transaction (which should disable autocommit in Doctrine):
$connection->beginTransaction();
The class UnitOfWork.php has a catch block like:
catch (Exception $e) {
$this->em->close();
$conn->rollback();
throw $e;
}
Of course, if your class is not ready to find an already closed entity manager and therefore connection, you will have this exception. The worst thing about it is that it masks the underlying cause of the exception, since the error was caused before the catch block being executed. To fix it, you can do a simple check in your class' catch block:
catch(Exception $e) {
if($conn->isTransactionActive()) {
[rollback]
[close]
[rethrow] (if necessary)
}
}
Found the problem.....I have called rollback() function 2 times in different places in the code
You can check if the transaction exists with transaction nesting level:
$this->em->getConnection()->getTransactionNestingLevel()
If nesting level exist grather than 0, then you can do a rollback

Categories