I'm trying to use same connection to my database between session handler and doctrine dbal:
config.yml
framework:
session:
handler_id: session.handler.one_connection_pdo
services.yml
session.handler.one_connection_pdo:
class: AppBundle\Session\OneConnectionPdoHandler
public: false
arguments:
- "@database_connection"
- []
AppBundle/Session/OneConnectionPdoHandler.php
namespace AppBundle\Session;
use Doctrine\DBAL\Connection;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
class OneConnectionPdoHandler extends PdoSessionHandler
{
public function __construct($pdoOrDsn, array $options)
{
if ($pdoOrDsn instanceof Connection) {
$pdoOrDsn = $pdoOrDsn->getWrappedConnection();
}
parent::__construct($pdoOrDsn, $options);
}
}
Everything seems to work when browsing application but I can't update any entity because I get error:
PDOException: There is already an active transaction
at n/a
in .../vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php line 1176
at PDO->beginTransaction()
in .../vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php line 1176
at Doctrine\DBAL\Connection->beginTransaction()
in .../vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php line 373
at Doctrine\ORM\UnitOfWork->commit(null)
in .../vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php line 356
at Doctrine\ORM\EntityManager->flush()
in .../src/AppBundle/Controller/Admin/DistributorsController.php line 66
at AppBundle\Controller\Admin\DistributorsController->editAction(object(Distributor), object(Request))
in line
at call_user_func_array(array(object(DistributorsController), 'editAction'), array(object(Distributor), object(Request)))
in .../vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php line 139
at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), '1')
in .../vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php line 62
at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), '1', true)
in .../vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php line 169
at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
in .../web/app_dev.php line 31
Is there a way to share connection between doctrine dbal and custom pdo handler?
// EDIT
I finally found a solution inside PdoSessionHandler
class.
By default PDO handler uses transaction when reading and writing to session. It start transaction on first read()
and commit on close()
. In between there were some database operation $em->persist($entity); $em->flush()
which spawned another transaction which generated error.
Inside PdoSessionHandler
class I found that there is a lock_mode
option which can be set like this:
session.handler.one_connection_pdo:
class: AppBundle\Session\OneConnectionPdoHandler
public: false
arguments:
- "@database_connection"
- { lock_mode: 1 }
When lock_mode is set to 1 (PdoSessionHandler::LOCK_ADVISORY
) PDO handler will use advisory lock instead of transaction and there will be no more transaction errors.
In Symfony 3~
in (app\config\config.yml):
framework:
session:
handler_id: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler
in (app\config\services.yml):
Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler:
arguments:
- !service { class: PDO, factory: 'database_connection:getWrappedConnection' }
- {lock_mode: 1 }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With