facile-it/doctrine-mysql-come-back

当Doctrine MySql出现“MySQL已断开连接”异常时,自动重连 doctrine/dbal

3.0.0 2024-03-10 11:32 UTC

README

Latest Stable Version Latest Unstable Version Total Downloads

Build status Test coverage License

DoctrineMySQLComeBack

这个库试图解决臭名昭著的“MySQL已断开连接”问题及其类似问题。

它是通过提供一个自动在适用情况下重新连接到数据库服务器的 doctrine/dbal 驱动包装器来实现的;为了避免一致性问题的,重连在写入操作(即打开事务、写入查询超时)时不会被尝试。

安装

如果你使用 DBAL 4.0+

$ composer require facile-it/doctrine-mysql-come-back ^3.0

如果你使用 DBAL 3.6+

$ composer require facile-it/doctrine-mysql-come-back ^2.0

如果你使用 DBAL ^2.3

$ composer require facile-it/doctrine-mysql-come-back ^1.0

配置

为了使用 DoctrineMySQLComeBack,你必须设置 wrapperClass 连接参数。你可以选择 Doctrine 应该能够重新连接的次数,设置 x_reconnect_attempts 驱动选项。其值必须为整数。

如果你使用 DBAL v2,还需要设置 driverClass 参数;请参阅 此说明的先前版本

连接实例化时配置的示例

use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\DriverManager;

$config = new Configuration();

//..

$connectionParams = [
    'dbname' => 'mydb',
    'user' => 'user',
    'password' => 'secret',
    'host' => 'localhost',
    // [doctrine-mysql-come-back] settings
    'wrapperClass' => 'Facile\DoctrineMySQLComeBack\Doctrine\DBAL\Connection',
    'driverOptions' => [
        'x_reconnect_attempts' => 3
    ],
];

$conn = DriverManager::getConnection($connectionParams, $config);

//..

Symfony项目中yaml配置的示例

doctrine:
    dbal:
        connections:
            default:
                # DATABASE_URL would be of "mysql://db_user:db_password@127.0.0.1:3306/db_name" 
                url: '%env(resolve:DATABASE_URL)%'
                wrapper_class: 'Facile\DoctrineMySQLComeBack\Doctrine\DBAL\Connection'
                options:
                    x_reconnect_attempts: 3

Laminas Framework 2项目中配置的示例

return [
    'doctrine' => [
        'connection' => [
            'orm_default' => [
                'wrapperClass' => \Facile\DoctrineMySQLComeBack\Doctrine\DBAL\Connection::class,
                'params' => [
                    'host' => 'localhost',
                    'port' => '3307',
                    'user' => '##user##',
                    'password' => '##password##',
                    'dbname' => '##database##',
                    'charset' => 'UTF8',
                    'driverOptions' => [
                        'x_reconnect_attempts' => 9,
                    ]
                ],
            ],
        ],
    ],
];

如果你使用主/从 Doctrine 配置,可以使用包装类 Facile\DoctrineMySQLComeBack\Doctrine\DBAL\Connections\PrimaryReadReplicaConnection

use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\DriverManager;

$config = new Configuration();

//..

$connectionParams = [
    'wrapperClass' => 'Facile\DoctrineMySQLComeBack\Doctrine\DBAL\PrimaryReadReplicaConnection',
    'primary' => [
        // ...
        'driverOptions' => [
            'x_reconnect_attempts' => 3
        ],
    ],   
];

$conn = DriverManager::getConnection($connectionParams, $config);

//..

使用

由于 DBAL v3,Connection::refresh 已不存在,因此你不需要做任何其他操作来利用重连,它将自动完成。

从这个库的 v1.6 版本开始,自动重连也在 $em->getConnection()->beginTransaction() 调用期间启用,如果不在先前的交易之外,它也适用于简单的 $em->flush()

感谢

感谢 Dieter Peeters 及其关于 DBAL-275 的提议。如果你使用 doctrine/dbal <2.3,请查看。