mysql pdo 事务和会话存储

Posted

技术标签:

【中文标题】mysql pdo 事务和会话存储【英文标题】:mysql pdo transaction and session storage 【发布时间】:2012-12-08 02:54:36 【问题描述】:

我很难确定我的网络应用程序的最佳解决方案是什么,该应用程序在每个会话中多次访问(主要是读取)相同的用户数据。

我应该在打开新会话时一次将所有用户数据(大约 40 个字段)检索到 $_SESSION,还是应该保持持久 PDO (mysql) 连接并在每次脚本执行时仅从数据库中查询我需要的参数?

另外:

在同一事务中一次读取/更新大量字段(使用自定义查询)或一个接一个(使用通用查询的自定义组合)在性能上会有很大差异吗?例如

$dbh = new PDO("mysql:host=localhost;dbname",$dbuser,$dbpass,array(PDO::ATTR_PERSISTENT => true));

$fieldlist='';
foreach ($fields as $i=>$field)
    $fieldlist.=$field['name'].':field'.$i.',';

rtrim($fieldlist,',');
$dbh->prepare("UPDATE user SET ".$fieldlist." WHERE name=:name");
foreach ($fields as $i=>$field)
    $stmt->bindValue(':field'.$i, $field['value'], PDO::PARAM_STR);

$stmt->bindValue(':name', $name, PDO::PARAM_STR);
$stmt->execute();

$dbh = null;

对比

$dbh = new PDO("mysql:host=localhost;dbname",$dbuser,$dbpass,array(PDO::ATTR_PERSISTENT => true));


$dbh->beginTransaction();

foreach($fields as $field)
    $stmt=$dbh->prepare("UPDATE user SET ".$field['name']."=:field WHERE name=:name");
    $stmt->bindValue(':field', $field['value'], PDO::PARAM_STR);
    $stmt->bindValue(':name', $name, PDO::PARAM_STR);
    $stmt->execute();


$dbh->commit();

$dbh = null;

【问题讨论】:

您不能将数据库连接资源序列化到会话中。我想说这解决了这场争论。 【参考方案1】:

会不会有很大的性能差异

我会说常识有所不同。 为什么要一个一个地重复,而你可以一次做呢?是否有理由为同一任务编写更多代码? 看来你是在寻找麻烦,而不是他们真正所在的地方。

【讨论】:

因为,根据场景(用户输入),我可能需要修改不同的参数组合。我对 ACID 事务还不是很熟悉,我想知道这与花时间优化查询相比有多大的瓶颈,所以当在同一个事务上修改特定表的多个列时,我'将语句加入一个查询中,而不是启动事务,执行所有语句然后提交... 无论如何,我想你想告诉我的是,使用 get/set 函数来检索/更新每个参数并不是一个好主意(这是我在开始之前从未想过的阅读有关 PDO 和 ACID 事务的信息),这就是我想知道的全部内容,但是正如您所看到的,我对这里的概念有点迷茫,所以如果您能指出一些关于该主题的文献,我将不胜感激你知道(除了 php 手册和***,我目前的参考资料)。非常感谢。【参考方案2】:

无法完成。即使你能做到这一点,这也是一个坏主意。您将创建一个具有大量并发打开连接的情况,这些连接将超过您的最大连接数。

我不确定为什么您必须不断地使用相同的数据更新会话。只需将数据放入会话中一次,即可完成。

如果您正在处理大型数据集,您可能需要考虑缓存。这将减少数据库负载。您可以使用 memcached。这将提高性能,它允许您指定要缓存的资源和数量。

【讨论】:

【参考方案3】:

您应该将数据保留在会话中。

您不能安全地将任何处理程序(在您的情况下为数据库连接)保持在会话中,因为下一个请求的标识符可能不同。此外,保持开放的连接以防万一可能不是最好的做法。

如果您以任何方式加载数据,只需保持会话 - 如果您每次查询它,您将使用至少相同数量的内存,但会执行数据库查询,因此与仅保持相比性能会更差数据。如果您需要在每次请求时刷新数据,只需使用新连接即可,不要尝试将连接处理程序保留在会话中。

【讨论】:

以上是关于mysql pdo 事务和会话存储的主要内容,如果未能解决你的问题,请参考以下文章

MySQL索引事务及存储引擎

使用 PDO 将会话存储在数据库中的 PHP 不会产生我预期的错误

MySQL事务与存储引擎

事务、存储过程和 PDO

由于 2 个会话同时访问相同的存储过程,导致事务(进程 ID)死锁

MySQL事物隔离级别及搜索引擎