In reference to this point: https://www.php.net/manual/en/pdo.begintransaction.php#109753
The following code works, but can it be run safely on production?
DB::beginTransaction();
try {
// update statements
DB::transaction(function(){
// update statements
});
// update statements
DB::commit();
} catch (Exception $e) {
DB::rollback();
}
Yes, it helps maintain the atomic state either the data gets stored or rollback.
Related
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.
I am using laravel 4 and trying to use commit and rollback functions. But functions are not working for me.
I am following laravel documentations (https://laravel.com/docs/4.2/database#database-transactions) but still its not working.
Here is my code :
DB::transaction(function() use ($product)
{
DB::table('products')->insert($product);
DB::rollBack();
});
Its creating new entry in products table. which is wrong.
In your example, the transaction will only be rolled back when there is an exception.
Note: Any exception thrown within the transaction closure will cause the transaction to be rolled back automatically.
You have to manually start your transaction with DB::beginTransaction() and end it with DB::rollback() or DB::commit()
It is also possible to do this within a try catch statement.
try {
DB::beginTransaction();
// Do something
DB::commit();
} catch (\Exception $e) {
DB::rollback();
throw $e;
}
I'm using Laravel 5.2.
I would like to know what are the differences between :
DB::beginTransaction() and DB::transaction()
DB::commitTransction() and DB::commit()
DB::rollbackTransction() and DB::rollback()
Any helps would be appreciated.
DB::beginTransaction() will only begin a transaction, while for DB::transaction() you must pass a Closure function that will be executed inside a transaction.
So this:
DB::transaction(function() {
// Do something and save to the db...
});
is the same as this:
// Open a try/catch block
try {
// Begin a transaction
DB::beginTransaction();
// Do something and save to the db...
// Commit the transaction
DB::commit();
} catch (\Exception $e) {
// An error occured; cancel the transaction...
DB::rollback();
// and throw the error again.
throw $e;
}
As you can see, DB::transaction() is a "helper" function to avoid writing code to catch errors, begin a transaction, commit the transaction, and optionally rollback (cancel the transaction) if an error occured.
If you have a more complex logic, or need an specific behaviour, you will manually build your transaction; if your logic is rather simple, DB::transaction() is the way to go.
As for DB::commitTransaction() and DB::rollbackTransaction(), I can't find information.
It's a good practice to check the source code of the things you use, because you will learn how they are written, as well as how to write. Here's the file with the source for these methods.
From Laravel 6 to use Transactions must be use the following helper functions.
use Illuminate\Support\Facades\DB;
try {
// For Begin a transaction
DB::beginTransaction();
// Do something
// Commit the transaction
DB:: commit();
} catch (\Throwable $e) {
// An error occured
DB::rollback();
// and throw the error again.
throw $e;
}
if you use the DB::commitTransaction(); function, get error undefined function.
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
}
I would like to use transaction in some critical areas of my code, but really not for everything I do.
I just learnt that there is an AUTOCOMMIT value that is set to 1 by default, and I should set it to 0 if I want to START TRANSACTION and COMMIT or ROLLBACK.
Is there a better way to handle that autocommit?
How do I know if it is set or not ?
Does it's value change to AUTOCOMMIT=1 on every page that loads?
Using PDO
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->beginTransaction();
try {
// do stuff
$pdo->commit();
} catch (Exception $ex) {
$pdo->rollBack();
throw $ex;
}