Laravel读写连接不同步

时间:2017-03-10 15:20:14

标签: php mysql laravel laravel-5.2

我在Laravel 5.2应用程序中使用读写MySQL连接设置:

'mysql' => [
    'write' => ['host' => env('DB_HOST_WRITE', 'localhost'),],
    'read'  => ['host' => env('DB_HOST_READ', 'localhost'),],
    'driver' => 'mysql',
    'port' => env('DB_PORT', '3306'),
    'database' => env('DB_DATABASE', 'forge'),
    'username' => env('DB_USERNAME', 'forge'),
    'password' => env('DB_PASSWORD', ''),
    'charset' => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix' => '',
    'strict' => false,
    'engine' => null
]

该网站使用负载均衡器在多台服务器上运行。

现在,在应用程序中,存在一个接一个地进行读写操作的情况,例如

  1. 将新记录插入数据库
  2. 选择一些新插入的记录
  3. 使用当前的连接设置,即使正确插入记录,也可能会发生选择不返回任何内容。

    这可能是什么原因?

2 个答案:

答案 0 :(得分:3)

在Laravel 5.5中,我为此做了一个PR,它引入了一个"粘性"选项。

这意味着您的应用程序将使用" read"尽可能连接,但是如果你做了#34;写",那么任何后续的"读取"在同一请求周期中也将来自写连接。

这可确保数据完整性。

https://github.com/laravel/framework/pull/20445

答案 1 :(得分:2)

这不是Laravel特有的问题。这称为主从复制滞后。

有多种预防技术,但只有一种技术可以治愈"问题

首先是治愈:避免读写组合

在插入(读写组合)后不要立即执行选择操作。这听起来可能很疯狂,但如果你可以避免它,那就避免它!

如果你不能这样做,但你可以确定代码中读写组合的位置,只需将master用于读写操作

预防技术(如果无法治愈)

  1. 启用slave compressed protocol
  2. 禁用从站上的二进制日志记录
  3. 优化mysql查询(例如添加索引等)
  4. 其他方式:在插入和选择查询之间手动休眠,在单个事务中包装插入和选择(再次使用主连接完成,而从属是免费的)