- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我们在 Symfony 1.4/Propel 1.4 中有一个现有项目(SNS 网站+android/Iphone 游戏)
我们在数据库服务器(比如 DB1)上遇到了额外的负载。我们正在进行数据库优化,但作为直接解决方案,我们决定再创建一个数据库服务器,因为 DB2 始终是 DB1 的精确副本。目前我们只有 DB1,用于读写操作。
现在我们需要将所有读取操作移至 DB2,并保持 DB1 上的写入操作(通常在事务中)保持原样。
进行这些更改的可能方法是什么(在生产服务器上没有太多停机时间),如果可能,代码更改最少。
第一条评论后编辑
根据 J0k 给出的链接和其他一些链接,我在本地开发环境中完成了以下操作。
更新database.yml如下
all:
propel:
class: sfPropelDatabase
param:
classname: PropelPDO
dsn: 'mysql:host=localhost;dbname=wzo;'
username: root
password: mysql
encoding: utf8
persistent: true
pooling: true
slaves:
slave1:
dsn: 'mysql:host=localhost;dbname=wzoslv;'
username: root
password: mysql
encoding: utf8
其中数据库 wzoslv
是数据库 wzo
的精确副本,除了一个测试条目中的更改。在表 odd_play
行 26 (PK) 列 result
条目分别是 WON1
和 WON
。/p>
运行 symfony 任务
php symfony propel:build-schema
php symfony propel:build-model
php symfony cc
创建了一个模块并添加了以下代码:
class wzoActions extends sfActions
{
public function executeIndex(sfWebRequest $request)
{
$con_write = Propel::getConnection(OddPlayPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
$con_read = Propel::getConnection(OddPlayPeer::DATABASE_NAME, Propel::CONNECTION_READ);
$oddPlay = OddPlayPeer::retrieveByPK(26,0,$con_write);
echo "on write connection, result=".$oddPlay->getResult();
$oddPlayRead = OddPlayPeer::retrieveByPK(26,0,$con_read);
echo "<br/>on Read connection, result=".$oddPlayRead->getResult();
exit;
$this->setLayout('layout');
}
}
在浏览器中运行http://local.sftest.com/index.php/wzo/index
,输出为,
on write connection, result=WON //Correct expected output
on Read connection, result=WON //Not correct. That should be WON1
我猜想在创建读/写连接时传递 OddPlayPeer::DATABASE_NAME
是个问题,但在线示例中是如何建议的。有人可以建议我在哪里犯了错误吗?
编辑:更多输入
我更新了 lib\vendor\symfony\lib\plugins\sfPropelPlugin\lib\vendor\propel\Propel.php
中的调试回显以检查它是如何返回连接的。发现是在进入下面的if(第544-549行)
$slaveconfigs = isset(self::$configuration['datasources'][$name]['slaves']) ? self::$configuration['datasources'][$name]['slaves'] : null;
if (empty($slaveconfigs)) {
echo "inelseifif<br/>";// no slaves configured for this datasource
self::$connectionMap[$name]['slave'] = false;
return self::getConnection($name, Propel::CONNECTION_WRITE); // Recurse to get the WRITE connection
}
其中 $slaveconfigs
为空,因此返回写入连接。现在的问题是,为什么 slaveconfigs 是空的?
我还尝试按照 old forums 中的定义编辑 sfDatabaseConfigHandler.class.php但是这样做会在某个地方破坏 symfony,并且不会在网络上什至日志中显示任何内容。
最佳答案
我确定我犯了一些错误,但无论是 Propel/symfony 的官方文档甚至是 stackoverflow 上的建议,似乎都不适合我。可能官方文档应该更好地照顾那些没有很多 symfony 经验的程序员。
虽然我们不喜欢编辑任何框架/第三方库的核心文件,但这迫使我编辑核心文件来为我制定一个可行的解决方案。对我有用的解决方案如下:
数据库.yml我的database.yml文件如下:
all:
propel:
class: sfPropelDatabase
param:
classname: PropelPDO
dsn: 'mysql:host=localhost;dbname=wzo;'
username: testuserwzo
password:
encoding: utf8
persistent: true
pooling: true
slave:
class: sfPropelDatabase
param:
classname: PropelPDO
dsn: 'mysql:host=localhost;dbname=wzoslv;'
username: testuserwzoslv
password:
encoding: utf8
persistent: true
pooling: true
之后,我编辑了 Propel.php 文件如下
适用于 Propel 1.4
文件:lib/vendor/symfony/lib/plugins/sfPropelPlugin/lib/vendor/propel/Propel.php
更改第 542-543 行
// we've already ensured that the configuration exists, in previous if-statement
$slaveconfigs = isset(self::$configuration['datasources'][$name]['slaves']) ? self::$configuration['datasources'][$name]['slaves'] : null;
with(中间加了一行)
// we've already ensured that the configuration exists, in previous if-statement
self::$configuration['datasources'][$name]['slaves'] = isset(self::$configuration['datasources']['slave']) ? self::$configuration['datasources']['slave'] : null;
$slaveconfigs = isset(self::$configuration['datasources'][$name]['slaves']) ? self::$configuration['datasources'][$name]['slaves'] : null;
然后在同一文件中,更改第 560 行
$con = Propel::initConnection($conparams, $name);
到
$con = Propel::initConnection($conparams, 'slave'); //I know its bad practive to put hard-coded value but at that moment, I was more interested in working solution without caring about best practices.
对于 propel 1.6(我们升级 propel 只是为了让它工作,但后来又恢复到 propel 1.4,因为生产升级需要经过充分测试。)
文件:plugins/sfPropelORMPlugin/lib/vendor/propel/runtime/lib/Propel.php
更改了第 601 行
$slaveconfigs = isset(self::$configuration['datasources'][$name]['slaves']) ? self::$configuration['datasources'][$name]['slaves'] : null;
到(前加一行)
self::$configuration['datasources'][$name]['slaves'] = isset(self::$configuration['datasources']['slave']) ? self::$configuration['datasources']['slave'] : null;
$slaveconfigs = isset(self::$configuration['datasources'][$name]['slaves']) ? self::$configuration['datasources'][$name]['slaves'] : null;
然后在同一文件中,更改第 629 行
$con = Propel::initConnection($conparams, $name);
到
$con = Propel::initConnection($conparams, 'slave');
然后下面的测试文件给出了预期的结果
class kapsActions extends sfActions
{
public function executeIndex(sfWebRequest $request)
{
$con_write = Propel::getConnection(OddPlayPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
$con_read = Propel::getConnection(OddPlayPeer::DATABASE_NAME, Propel::CONNECTION_READ);
$oddPlay = OddPlayPeer::retrieveByPK(28,0,$con_write);
echo "on write connection, result=".$oddPlay->getResult().$oddPlay->getPlayscore();
$oddPlayRead = OddPlayPeer::retrieveByPK(27,0,$con_read);
echo "<br/>on Read connection, result=".$oddPlayRead->getResult().$oddPlayRead->getPlayscore();
exit;
//$this->setLayout('layout');
}
}
我仍然不建议编辑核心文件,但这个解决方案在紧急情况下对我们有用。如果需要,其他人可以在紧急情况 中使用它。仍在寻找完美的解决方案。
关于php - Symfony/Propel 1.4 : Read from one, 写入其他数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13234058/
我有一个阅读器,其中包含有关 51*51 网格的信息,其中网格上的每个点都由 f32 表示。 .我想将这些数据读入一个向量,以便我可以轻松处理它: pub fn from_reader(reader:
我重新启动了 SQL Server 2005 并运行了统计 IO 的查询。 我得到了这些结果:表“xxx”。扫描计数 1,逻辑读取 789,物理读取 3,预读读取 794,... 预读读取数是读取并放
在 CLHS 中,我为 :read-only x 读到:“当 x 为真时,这指定不能更改此插槽;它将始终包含构造时提供的值。” 我可以做到这一点(CCL、SBCL): CL-USER> (defstr
让我们考虑一下这句话(Total Store Ordering): reads are ordered before reads, writes before writes, and reads be
我正在开发一个 SMTP 库,它使用缓冲读取器通过网络读取行。 我想要一种安全的方式来从网络读取数据,而不依赖于 Rust 内部机制来确保代码按预期工作。具体来说,我想知道 Read trait 是否
我不清楚所有这些读取字符串函数之间的关系。嗯,很明显clojure.core/read-string可以读取 pr[n] 输出的任何序列化字符串甚至 print-dup .也很清楚clojure.ed
所以我做了这个功能,就像倒计时一样。我想在倒计时减少时读取命令。我的大问题是让 read() 在倒计时减少时等待输入。如您所见,我尝试使用 select() 但在第一个 printf 之后("time
这是我vue3+echart5 遇到的报错:Cannot read properties of undefined (reading ‘type‘) 这个问题需要搞清楚两个关键方法: toRaw: 作
下图中,左边是C代码,右边是未优化的LLVM IR形式。 The Figure 在 IR 上运行 MemoryDependenceAnalysis 可查找内存依赖性。原始代码及其 IR 等效代码中
这个问题在这里已经有了答案: Read values into a shell variable from a pipe (17 个答案) 关闭 3 年前。 我一直在尝试像这样从程序输出中读取环境变
当我输入相同的整数时,如何将整数转换为与使用 read(0,buff,nbytes) 获得的缓冲区相同的值/编码字符?我正在尝试编写类似 read() 的东西,但用整数数据代替读取到缓冲区的文件描述符
This question already has answers here: Closed 2 years ago. Read input in bash inside a while loop (
我正在尝试处理来自 MySQL 数据库的一些数据(主要是 double 值)。我收到此错误消息: Invalid attempt to access a field before calling Re
我正在制作一个简单的 TCP/IP 套接字应用 这样做有什么不同: DataInputStream in = new DataInputStream(clientSocket.getInputStre
我操作API服务器。 手机APP访问API服务器时,有时会出现该异常。 我尝试在测试服务器上进行测试,但无法重现。(我改变了apache和tomcat的连接时间。) 有什么问题?? 我该如何解决这个问
我在段落末尾使用“阅读更多”只是为了提醒像P.T.O一样的用户 为什么会有问题? 最佳答案 您必须明白,许多屏幕阅读器用户不会等到整个页面都读给他们听。他们使用键盘快捷键在页面中导航。 JAWS(可以
我已将我的 Angular 应用程序从 12 版本升级到 13 版本。我在单元测试运行期间开始遇到此错误。 Chrome Headless 94.0.4606.61 (Windows 10) AppC
我正在尝试为以下组件编写一个。我正在使用 queryParams 然后使用 switchmap 来调用服务。这是 url 的样子: http://localhost:4200/test-fee/det
我的代码有什么问题? Uncaught TypeError: Cannot read properties of undefined (reading 'remove') 和 Uncaught Typ
我在我的 React 应用程序中遇到了这个问题。 类型错误:无法读取未定义的属性(读取“requestContent”) 我在我的应用程序中使用 commercejs。代码指向 isEmpty=!ca
我是一名优秀的程序员,十分优秀!