改进的MySQL连接池PDO

v1.0.1 2021-02-14 22:10 UTC

This package is auto-updated.

Last update: 2024-09-15 05:23:14 UTC


README

此库提供与 PDO API 匹配的类,并且可以用于几乎不需要修改应用程序的情况下替换 PDO。此类称为 Pdoi。它支持大多数(但不全部)PDO功能。对于MySQL以外的驱动程序,它的工作方式与 PDO 完全相同(函数调用被转发到内部 PDO 实例),而对于MySQL,它明确使用 mysqli 扩展。

这是为了实现两个目标

  1. 更合理的连接池。
  2. 访问 mysqli 特定功能。

关于数据库连接池

截至2021年1月,我在PHP世界中看不到可用的数据库连接池解决方案。

可以使用 "p:" 前缀为主机名创建 mysqli 的持久连接。而通过 PDO,它们可以通过 PDO::ATTR_PERSISTENT 属性来创建。与PHP-FPM进程池一起,这可以构建真正的数据库连接池系统。

即使在PHP4上也能工作,但没有人实际使用它们,因为存在重用脏连接的问题。

  1. 一次发出的 SET @flag=1 将在下次连接使用时初始化设置。
  2. 开始且未提交的事务将持有受影响的行上的锁。
  3. SELECT Get_lock('Busy', 10) 将阻止池中其他并行连接进入关键部分。

截至2021年1月,mysqliPDO 中当前的持久连接实现通过调用 mysqli_change_user() 函数重置连接状态。但我的经验表明,用户锁没有被释放。我猜想这个函数在从池中选取连接并使用它之前被调用。因此,从连接被单独留下到新使用(可能根本不会发生)的整个时间段内,锁都锁定着它们想要锁定的东西。

每个连接应在脚本结束时立即重置。此库在 Pdoi 对象的析构函数中调用 mysqli_change_user()。我喜欢PHP中的引用计数对象,以及析构函数在对象不再使用时立即被调用。

安装

为您的应用程序创建一个目录,切换到该目录,并执行

composer require jeremiah-shaulov/pdoi

示例

<?php

require_once 'vendor/autoload.php';
use Pdoi\Pdoi as Pdo;

$db = new Pdo
(	'mysql:host=localhost',
	'root',
	'',
	[	PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
		PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
		PDO::MYSQL_ATTR_MULTI_STATEMENTS => false,
		PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false,
		PDO::ATTR_PERSISTENT => true,
	]
);

var_dump($db->query("SELECT Connection_id()")->fetchColumn());

从CLI运行此示例将每次显示不同的 Connection_id(),因为进程生命周期中只有一个连接。但从PHP-FPM运行将显示相同的连接号出现多次。