How to disable Save Points?
I'm using Firebird with this lib: https://github.com/harrygulliford/laravel-firebird
As far I understand this lib doesn't have support for transactions.
I had a problem while running nested transactions inside a foreach that when thrown an exception in the "parent" transaction scope it rolled back only the last one inserted in the foreach.
Digging deep I found that here: vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php
It calls the method $this->queryGrammar->supportsSavepoints and it's fixed a "true".
If I modify it to return false (since I believe the lib didn't support anyway) then everything works as expected.
Since I'm not that great of a programmer I'm here to ask if should I do it? and more important how? I'm not sure how to do it without editing the vendor which isn't really the way to go I believe.
Heres the code I used to test the behavior:
public function store(FaturamentoStoreRequest $request)//: FaturamentoResource
{
try {
Transaction::start();
Cidade::create(['NOME' => 'CIDADE PAI']);
for ($i = 0; $i < 10; $i++) {
$this->novaTransacao($i);
}
throw new \Exception('asdfg');
Transaction::commit();
} catch (\Throwable $th) {
Transaction::rollback('rolou back');
throw $th;
}
return response()->json(['Ok']);
}
private function novaTransacao($i)
{
try {
Transaction::start();
Cidade::create(['NOME' => 'CIDADE F1 ' . $i]);
$this->novaTransacao2($i);
Transaction::commit();
} catch (\Throwable $th) {
Transaction::rollback($th->getMessage());
throw $th;
}
}
private function novaTransacao2($i)
{
try {
Transaction::start();
Cidade::create(['NOME' => 'CIDADE F2 ' . ($i + 1)]);
// if ($i = 2) {
// throw new \Exception('asdfg');
// }
Transaction::commit();
} catch (\Throwable $th) {
Transaction::rollback($th->getMessage());
throw $th;
}
}
It's strange because it happens only inside a foreach and it is indeed respecting the transaction levels (only really commit (doCommit) when transaction level = 1.
Since it's Firebird and lib doesnt have support for Transactions we created this lib to make it sort of work:
class Transaction
{
public static function start()
{
DB::getPdo()->setAttribute(PDO::ATTR_AUTOCOMMIT, 0);
DB::beginTransaction();
}
public static function commit()
{
DB::commit();
DB::getPdo()->setAttribute(PDO::ATTR_AUTOCOMMIT, 1);
}
public static function rollback()
{
DB::rollback();
DB::getPdo()->setAttribute(PDO::ATTR_AUTOCOMMIT, 1);
}
}
Any insight is very welcome, thanks in advance.
Please or to participate in this conversation.