我使用Symfony2中的Doctrine2主/从配置在单个主数据库和几个只读(复制)从数据库中扩展我的应用程序。
这在我的应用程序中运行得很好,Doctrine2明智地将slave用于只读查询,将master用于写入操作。
如果在我的一个控制器中,我写道:
$em = $this->get('doctrine')->getManager();
var_dump($em->getConnection()->isConnectedToMaster());
isConnectedToMaster()
返回false
——这是我所期望的,因为从设备默认连接到它。
如果我在WebTestCase
中运行此代码,情况也是如此
但是,如果我在Symfony控制台命令(ContainerwareCommand)中编写了完全相同的代码:
$em = $this->getContainer()->get('doctrine')->getManager();
var_dump($em->getConnection()->isConnectedToMaster());
isConnectedToMaster()
返回true。这意味着选择主控形状作为默认值。
我找不到如何从控制台命令中停止默认连接为主。这意味着,如果我想从控制台运行一些非关键的、繁重的数据处理任务,它们都会命中主任务(坏),而不是从任务(好)。
有人知道我如何让Doctrine2在控制台默认使用从属服务器吗?或者知道为什么它总是默认为master吗?
回答:感谢nifr让我走上了正确的道路-我发现我的问题是因为我使用了JMS\JobQueueBundle(它用一个经过修改的应用程序替换了应用程序/控制台使用的应用程序,该应用程序必须以强制选择"master"的方式连接到MasterSlaveConnection)。当我评论时
use JMSJobQueueBundleConsoleApplication;
在app/console
中,在控制台测试中正确选择了从机。
感谢
您必须确保您的命令不会调用任何让条令选择主连接的操作。
对于理解MasterSlaveConnection
来说,重要的是它应该如何以及何时选择从机或主机。
- 如果以前从未拾取过主,则拾取"从",并且仅当使用了"getWrappedConnection"或"executeQuery"时
- 当调用">exec"、">executeUpdate'、">insert"、">delete'、">update"、">createSavepoint>"、">releaseSavepoint"、">beginTransaction"、">rollback‘、">commit’、">query或">
- 如果在连接的生存期内主节点被选中一次,则它将始终在之后被选中
- 在请求过程中随机选择一个从属连接一次
(MasterSlaveConnection API)
当我在寻找一种方法来询问我的主人写作或奴隶阅读时,我遇到了这个问题。
神奇之处在于:
-
写入操作(使用master):
$em->getConnection()->executeUpdate(...);
-
读取操作(使用从机):
$em->getConnection()->executeQuery(...);