我使用symfony4与现有的主/从mysql设置接口,并使用原始sql对服务器执行查询。原始sql是目前唯一的选择。
我正在使用show full processlist;在db服务器上监视使用哪个db,我只看到到主服务器的连接。似乎没有奴隶被使用过。
作为参考,我设置了两个dbal连接,默认值不是master/slave,并使用ormMap。第二个是我遇到问题的主/从服务器,这是我对其执行原始sql查询的服务器。
以下是我的信条.yml:
doctrine:
dbal:
default_connection: default
connections:
default:
driver: pdo_mysql
host: "%env(DATABASE_HOST)%"
dbname: "db1"
user: "%env(DATABASE_USER)%"
password: "%env(DATABASE_PASS)%"
charset: UTF8
ds:
driver: pdo_mysql
host: "%env(DS_DATABASE_HOST)%"
dbname: "db2"
user: "%env(DS_DATABASE_USER)%"
password: "%env(DS_DATABASE_PASS)%"
slaves:
slave1:
host: "%env(DS_DATABASE_SLAVE1_HOST)%"
user: "%env(DS_DATABASE_USER)%"
password: "%env(DS_DATABASE_PASS)%"
dbname: "db2"
slave2:
host: "%env(DS_DATABASE_SLAVE2_HOST)%"
user: "%env(DS_DATABASE_USER)%"
password: "%env(DS_DATABASE_PASS)%"
dbname: "db2"
orm:
default_entity_manager: default
entity_managers:
default:
connection: default
mappings:
Main:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity/Main'
prefix: 'App\Entity\Main'
alias: Main
ds:
connection: ds
我在my services.yml中配置了实体管理器,如下所示:
# Entity managers
App\Service\Database\MainEntityManager:
arguments:
$wrapped: '@doctrine.orm.default_entity_manager'
App\Service\Database\DSEntityManager:
arguments:
$wrapped: '@doctrine.orm.ds_entity_manager'
实体管理器(在本例中是dsentitymanager)被注入到类的构造函数中,然后按如下方式执行查询:
$result = $this->em->getConnection()->prepare($sql);
$result->execute($args);
如果缺少任何有用的配置,请告诉我。
非常感谢你的帮助。
1条答案
按热度按时间vd2z7a6w1#
谢谢@cerad的提示,这让我找到了正确的方向。因为我不再尝试对未Map到实体的原始查询使用实体管理器,所以我可以直接使用连接。
我创建了一个 Package 类来扩展masterslaveconnection。只要我使用executequery(),它就可以工作。根据文档,必须使用它来查询从机。但是,我的查询需要使用prepare()和query(),这两种方法都强制主连接。
因此,在我的新 Package 类中,我创建了两个新方法prepareslave()和queryslave(),它们的作用与原来的相同;但是,它们执行$this->connect('slave');而不是$this->connect('master');
现在我所有的read查询都命中slave,其他所有查询都命中master。
因此,以下是我对上述配置所做的以下更新:
条令.yml
服务.yml
我的新 Package 类
所以现在如果我需要执行一个通常需要使用prepare()和query()的查询,我就使用prepareslave()和queryslave()。