如何在 SQL Server 的 Doctrine 2 中更改 DQL 查询中的 LockMode
Posted
技术标签:
【中文标题】如何在 SQL Server 的 Doctrine 2 中更改 DQL 查询中的 LockMode【英文标题】:How to change the LockMode in a DQL query, in Doctrine 2 for SQL Server 【发布时间】:2016-02-16 09:54:26 【问题描述】:我需要更改 LockMode 以让 Doctrine 将“with(nolock)”行为添加到我在 Query 中使用的表中。
我会更好地解释这一点:
我有什么:
SELECT e FROM Porject:Example e
我想从 Doctrine 创建和执行 SQL 时得到什么:
SELECT e FROM example e WITH(NOLOCK)
我无法找到如何在任何地方更改 LOCKMODE,这变得很痛苦。
我尝试打开一个事务并执行setLockMode(LockMode::NONE)
,但它只是在第一个表(FROM 子句中的那个)之后添加了with(nolock)
,我需要它在每个表中添加它(连接上的表) )。
我真正拥有的:
SELECT e, o FROM Porject:Example e JOIN e.owner o
我做了什么:
$dql='SELECT e, o FROM Porject:Example e JOIN e.owner o';
$query = $this->getEntityManager()->createQuery($dql);
try
$this->getEntityManager()->getConnection()->beginTransaction();
$result = $query ->setLockMode(LockMode::NONE)->getSQL();
$this->getEntityManager()->getConnection()->commit();
catch (\Exception $e)
$this->getEntityManager()->getConnection()->rollback();
throw $e;
成为$result
:
SELECT c0_.prop1, c0_.prop2, c1_.prop1, c1_.prop2
FROM examples c0_ WITH(NOLOCK)
INNER JOIN owners c1_ ON c1_.id= c0_ownerId`
我所期待的:
SELECT c0_.prop1, c0_.prop2, c1_.prop1, c1_.prop2
FROM examples c0_ WITH(NOLOCK)
INNER JOIN owners c1_ WITH(NOLOCK) ON c1_.id= c0_ownerId`
注意双重WITH(NOLOCK)
可能的解决方案:
try
$this->getEntityManager()->getConnection()->beginTransaction();
$this->getEntityManager()->getConnection()->setTransactionIsolation(\Doctrine\DBAL\Connection::TRANSACTION_READ_UNCOMMITTED);
$result = $query->getArrayResult();
$this->getEntityManager()->getConnection()->commit();
catch (\Exception $e)
$this->getEntityManager()->getConnection()->rollback();
throw $e;
但我不确定使用with(nolock)
是否与使用READ_UNCOMMITTED
相同隔离级别。
将@chalasr 的答案设置为已接受的答案。创建另一个问题来解决实际问题:How perform lockmode:none on associations (join) with Doctrine2 and SQL Server
仅供参考。
【问题讨论】:
【参考方案1】:有 4 个不同的LockMode
:
const NONE = 0;
const OPTIMISTIC = 1;
const PESSIMISTIC_READ = 2;
const PESSIMISTIC_WRITE = 4;
在documentation 中找到最合适的并像这样使用:
$query = $em->createQuery('SELECT e FROM Porject:Example e');
$query->setLockMode(LockMode::NONE);
【讨论】:
我只是在尝试,但它抱怨:“此操作需要一个开放的交易。”。 用新状态更新我的第一个 POST。问题没有完全解决。 啊,这真的是一个不同的问题......寻找将您的查询分成两部分,为每个设置锁定模式,我会寻找并回复您。 您应该针对如何在关联(加入)上执行锁定模式提出另一个问题 我尝试了不同的方法,我不知道它是否完全等效(编辑了第一篇文章)。非常感谢。以上是关于如何在 SQL Server 的 Doctrine 2 中更改 DQL 查询中的 LockMode的主要内容,如果未能解决你的问题,请参考以下文章
使用 Symfony2 和 Doctrine 的 SQL Server 数据库连接
Doctrine - 如何打印出真正的 sql,而不仅仅是准备好的语句?
Symfony 和 Doctrine 1.2.2:如何获取 Doctrine_Query 对象的 SQL 子句?