在DBAL和会话处理程序Symfony2之间共享与数据库的连接



我正在尝试在会话处理程序和 doctrine dbal 之间使用相同的数据库连接:

配置.yml

framework:
    session:
        handler_id:  session.handler.one_connection_pdo

服务.yml

session.handler.one_connection_pdo:
    class:     AppBundleSessionOneConnectionPdoHandler
    public:    false
    arguments:
        - "@database_connection"
        - []

AppBundle/Session/OneConnectionPdoHandler.php

namespace AppBundleSession;

use DoctrineDBALConnection;
use SymfonyComponentHttpFoundationSessionStorageHandlerPdoSessionHandler;
class OneConnectionPdoHandler extends PdoSessionHandler
{
    public function __construct($pdoOrDsn, array $options)
    {
        if ($pdoOrDsn instanceof Connection) {
            $pdoOrDsn = $pdoOrDsn->getWrappedConnection();
        }
        parent::__construct($pdoOrDsn, $options);
    }
}

浏览应用程序时一切似乎都正常,但我无法更新任何实体,因为我收到错误:

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 DoctrineDBALConnection->beginTransaction()
    in .../vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php line 373
at DoctrineORMUnitOfWork->commit(null)
    in .../vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php line 356
at DoctrineORMEntityManager->flush()
    in .../src/AppBundle/Controller/Admin/DistributorsController.php line 66
at AppBundleControllerAdminDistributorsController->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 SymfonyComponentHttpKernelHttpKernel->handleRaw(object(Request), '1')
    in .../vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php line 62
at SymfonyComponentHttpKernelHttpKernel->handle(object(Request), '1', true)
    in .../vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php line 169
at SymfonyComponentHttpKernelKernel->handle(object(Request))
    in .../web/app_dev.php line 31

有没有办法在学说 dbal 和自定义 pdo 处理程序之间共享连接?

//编辑

我终于在课堂上找到了解决方案PdoSessionHandler

默认情况下,PDO处理程序在读取和写入会话时使用事务。它在第一个read()开始事务,并在close()提交。在这两者之间有一些数据库操作$em->persist($entity); $em->flush()产生了另一个产生错误的事务。

在类PdoSessionHandler我发现有一个lock_mode选项可以像这样设置:

session.handler.one_connection_pdo:
    class:     AppBundleSessionOneConnectionPdoHandler
    public:    false
    arguments:
        - "@database_connection"
        - { lock_mode: 1 }

当lock_mode设置为 1 (PdoSessionHandler::LOCK_ADVISORY) 时,PDO 处理程序将使用咨询锁而不是事务,并且不会再有事务错误。

In Symfony 3~

在 (app\config\config.yml) 中:

framework:
    session:
     handler_id: SymfonyComponentHttpFoundationSessionStorageHandlerPdoSessionHandler

在 (app\config\services.yml) 中:

 SymfonyComponentHttpFoundationSessionStorageHandlerPdoSessionHandler:
        arguments:
            - !service { class: PDO, factory: 'database_connection:getWrappedConnection' }
            - {lock_mode: 1 }

最新更新