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