Multiple db transaction in one queue laravel 6.5.0 - laravel

Anyone have experience using laravel job with multiple database transaction in one queue?
does laravel support it.
I have an issue, i have 2 different database connection which is database A and database B, when i dispatch my first job using database A everything is working, all my data insert correctly, but when i dispatch my second job using database B , the transaction does not commit and no data insert at all
i need to restart the worker then it will work again.
im using redis as queue driver.
Database A Transaction
$valid = true;
DB::beginTransaction();
try {
//some logic happen here if got error $valid will be false
//if valid true commit else rollback
$valid ? DB::commit() : DB::rollback();
} catch (Exception $e) {
$valid = false;
DB::rollback();
}
Database B Transaction
$valid = true;
DB::beginTransaction('b-connection');
try {
//some logic happen here if got error $valid will be false
//if valid true commit else rollback
$valid ? DB::connection('b-connection')->commit() : DB::connection('b-connection')->rollback();
} catch (Exception $e) {
$valid = false;
DB::connection('b-connection')->rollback();
}
How I dispatch job
DeliveryOrderJob::dispatch($data)->onConnection('swift')->onQueue('do');
Basically both using the same logic, the only different is database connection. Please help.

You don't need to write rollback function in try{}. If that logic will fail or any other error occur then the catch Exception will rollback it.
\DB::connection('b-connection')->beginTransaction();
try {
\DB::connection('b-connection')->commit();
}catch (Exception $e) {
$valid = false;
DB::connection('b-connection')->rollback();
}

Related

Laravel: Could not insert data but don't catch any error

I try to run a cronjob to insert about 60000 rows into DB:
DB::beginTransaction();
try {
DB::table('pharmacies')->delete();
foreach(array_chunk($data, 50) as $piece) {
Pharmacy::insert($piece);
}
DB::commit();
\Log::debug("Save successfully");
} catch(\Exception $e) {
DB::rollback();
\Log::debug($e->getMessage());
}
}
The cronjob is working normally. I test for a few first times, it saves successfully. But then, It suddenly can't save and from this time the data can't save without any error.
I don't know why the data can't save but it doesn't catch exceptions to log the error message?
Any idea or suggestion for this case. Please help me. Thank you so much!
What is your CORN-JOB configuration? check /var/log/syslog for logs

doing something after Laravel's http client exception

I need to access to an online file and reading is content, but if for some reason the file isn't available due network/server problem ill use a local version stored on my server.
For doing that I've written this simple code:
$response = Http::timeout(2)->get('http.site/file.json');
And I add this for checking if all is ok:
if($response->successful()){
$list = $response->body();
} else {
$list = file_get_contents(asset('storage/list.json'));
}
But if I have a problem (for testing I just add a not correct address) of connection an exception is thrown and I cannot go into "else" part.
So I add a "try, catch":
try{
$response = Http::timeout(2)->get('http.site/file.json');
return $response->body();
}catch (Exception $ex) {
return file_get_contents(asset('storage/pharmaciesList.json'));
}
which is the correct way to treat this kind of code, and is it correct using a try catch without taking care of the exception?
Of course it's the right way, every function that could throw an exception should be enclosed in a try catch block. Otherwise (you said you're using Laravel) you can handle that exception in the exception handler.

How to find started transaction?

Controller code:
public function update(ContractTypeStoreAndUpdateRequest $request, ContractType $contractType): ContractTypeResource
{
$contractType->is_active = $request->input('is_active');
$contractType->name = $request->input('name');
$contractType->short_name = $request->input('short_name');
$contractType->description = $request->input('description');
$pdo = DB::connection()->getPdo();
$pdo->exec('SET TRANSACTION ISOLATION LEVEL READ COMMITTED');
DB::beginTransaction();
if ($request->has('feature')) {
if ($contractType->contracts()->count() !== 0) {
throw ValidationException::withMessages(
[
'feature' => 'Тип договора имеет привязанный договор изменить невозможно',
]
);
}
$contractType->feature = $request->input('feature');
}
$contractType->save();
DB::commit();
return ContractTypeResource::make($contractType);
}
When I run test on this enpoint I am getting the following error:
Active sql transaction: 1568 Transaction characteristics can't be
changed while a transaction is in progress
I understand the error message but I cannot assume where transaction might start before?
Do Laravel under the hood do something with transaction (validation, authentication)?
How to find the place where transaction has started before?
I got the reason.
My tests use this trait \Illuminate\Foundation\Testing\DatabaseTransactions
It covers test in transaction. In the end does rollback to keep database clean.

Batch update not working in pgsql database laravel

I want to update data by batch that always goes to catch. I am using pgsql database.
I followed this tutorial
https://github.com/mavinoo/laravelBatch
$tbc = $this->gradeService->updateGrade($request);
try{
if(count($tbc) > 0)
\Batch::update('grades',$tbc,'id');
}catch(\Exception $e){
return "OOps, an error occured";
}
return back()->with('status', 'Saved');
This part of code always execute catch. How can i solve this problem?

MySQL INSERT not inserting

Here's my code for making an entry into the MySQL db using PDO.
$sql="INSERT INTO dictionary (entry, meaning) VALUES (:entry,:meaning)";
$prep=$db->prepare($sql);
$prep->bindParam(':entry',$entry);
$prep->bindParam(':meaning',$meaning);
try{
$result=$prep->execute();
}
catch(PDOException $e)
{
echo $e->getMessage();
}
But it's not inserting anything on the db. What could be the problem?
Well, it is useless to ask other people what is wrong with your code. You have to ask your server instead.
So, make sure your PDO throws exceptions on errors. To do so, add this line after connection code
$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
Next, move try higher in the code
try{
$sql = "INSERT INTO dictionary (entry, meaning) VALUES (:entry,:meaning)";
$prep = $db->prepare($sql);
$prep->bindParam(':entry',$entry);
$prep->bindParam(':meaning',$meaning);
$result=$prep->execute();
} catch(PDOException $e) {
echo $e->getMessage();
}
and in case of any error you'll be notified of it.

Resources