pio*_*kkr 5 connection session pdo symfony doctrine-orm
我正在尝试在会话处理程序和学说 dbal 之间使用与我的数据库相同的连接:
配置文件
framework:
session:
handler_id: session.handler.one_connection_pdo
Run Code Online (Sandbox Code Playgroud)
服务.yml
session.handler.one_connection_pdo:
class: AppBundle\Session\OneConnectionPdoHandler
public: false
arguments:
- "@database_connection"
- []
Run Code Online (Sandbox Code Playgroud)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
浏览应用程序时似乎一切正常,但我无法更新任何实体,因为出现错误:
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
Run Code Online (Sandbox Code Playgroud)
有没有办法在学说 dbal 和自定义 pdo 处理程序之间共享连接?
// 编辑
我终于在PdoSessionHandler课堂上找到了解决方案。
默认情况下,PDO 处理程序在读取和写入会话时使用事务。它首先启动事务read()并提交close()。在两者之间有一些数据库操作$em->persist($entity); $em->flush()产生了另一个产生错误的事务。
在PdoSessionHandler课堂上我发现有一个lock_mode选项可以这样设置:
session.handler.one_connection_pdo:
class: AppBundle\Session\OneConnectionPdoHandler
public: false
arguments:
- "@database_connection"
- { lock_mode: 1 }
Run Code Online (Sandbox Code Playgroud)
当 lock_mode 设置为 1 ( PdoSessionHandler::LOCK_ADVISORY) 时,PDO 处理程序将使用咨询锁而不是事务,并且不会再有事务错误。
小智 4
在 Symfony 3 中~
在(应用程序\配置\config.yml)中:
framework:
session:
handler_id: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler
Run Code Online (Sandbox Code Playgroud)
在(应用程序\配置\services.yml)中:
Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler:
arguments:
- !service { class: PDO, factory: 'database_connection:getWrappedConnection' }
- {lock_mode: 1 }
Run Code Online (Sandbox Code Playgroud)