伍佰目录 短网址
  当前位置:海洋目录网 » 站长资讯 » 站长资讯 » 文章详细 订阅RssFeed

PHP - Manual: 事务

来源:网络转载 浏览:25407次 时间:2023-08-20
XA/Distributed Transactions » « SQL Hints (SQL 优化器)
  • PHP 手册
  • 函数参考
  • 数据库扩展
  • 针对各数据库系统对应的扩展
  • MySQL
  • mysqlnd_ms
  • 快速入门与例子

事务

当前版本的插件并不是事务安全的,因为他并没有识别全部的事务操作。 SQL 事务单元是在单一服务器中运行的。插件并不能有效的知道事务单元 何时开始,何时终止。所以,在事务单元中,可能数据库连接会被切换。

如果应用没有设定事务单元编辑,那么没有任何 MySQL 负载均衡能够检测他。

可以通过 SQL hints 来解除这个限制。可以选择性的调用事务 API 进行监控, 然后嗲用 API 执行控制事务。下面给出范例:

Example #1 配置一个 master 和一个 slave 的插件

[myapp]
{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "192.168.2.27",
                "port": "3306"
            }
        }
    }
}

Example #2 在事务中使用 SQL hints

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (!$mysqli)
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* 不是 SELECT 开头,所以使用 master */
if (!$mysqli->query("START TRANSACTION")) {
 /* Please use better error handling in your code */
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}

/* 禁止连接切换*/
if (!$mysqli->query(sprintf("/*%s*/INSERT INTO test(id) VALUES (1)", MYSQLND_MS_LAST_USED_SWITCH)))) {
 /* Please do proper ROLLBACK in your code, don't just die */
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}
if ($res = $mysqli->query(sprintf("/*%s*/SELECT COUNT(*) AS _num FROM test", MYSQLND_MS_LAST_USED_SWITCH)))) {
  $row = $res->fetch_assoc();
  $res->close();
  if ($row['_num'] > 1000) {
   if (!$mysqli->query(sprintf("/*%s*/INSERT INTO events(task) VALUES ('cleanup')", MYSQLND_MS_LAST_USED_SWITCH)))) {
     die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
   }
  }
} else {
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}
if (!$mysqli->query(sprintf("/*%s*/UPDATE log SET last_update = NOW()", MYSQLND_MS_LAST_USED_SWITCH)))) {
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}
if (!$mysqli->query(sprintf("/*%s*/COMMIT", MYSQLND_MS_LAST_USED_SWITCH)))) {
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}

$mysqli->close();
?>

自从 PHP 5.4.0 版本开始,mysqlnd library 允许插件监控 autocommit 模式下的状态,例如调用 SET AUTOCOMMIT=0 这样的语句,这将让插件开始关心事务处理。这样你就可以不用使用 SQl hints。

从 PHP 5.4.0 版本开始,调用 API autocommit 模式,插件设定中有 trx_stickiness=master, 那么插件将在事务中自动禁止负载均衡和连接切换。在 autocommit 禁用的配置当中, 插件将在事务过程中将所有的语句发送给 master,禁用负载均衡。当 autocommit 重新启用以后,插件将重新开始负载均衡所有的语句。

在 PHP 5.5.0 和 PECL/mysqlnd_ms 1.5.0 版本后,这种检查将不仅仅检查 mysqli_autocommit() 还会检查 mysql_commit()mysql_rollback()

Example #3 事务相关负载均衡下的 trx_stickiness 设置

{
    "myapp": {
        "master": {
            "master_0": {
                "host": "localhost",
                "socket": "\/tmp\/mysql.sock"
            }
        },
        "slave": {
            "slave_0": {
                "host": "127.0.0.1",
                "port": "3306"
            }
        },
        "trx_stickiness": "master"
    }
}

Example #4 Transaction aware

<?php
$mysqli = new mysqli("myapp", "username", "password", "database");
if (!$mysqli)
  /* Of course, your error handling is nicer... */
  die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* 禁用 autocommit,插件将所有语句发送给 master */
$mysqli->autocommit(FALSE);

if (!$mysqli->query("INSERT INTO test(id) VALUES (1)")) {
 /* Please do proper ROLLBACK in your code, don't just die */
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}
if ($res = $mysqli->query("SELECT COUNT(*) AS _num FROM test")) {
  $row = $res->fetch_assoc();
  $res->close();
  if ($row['_num'] > 1000) {
   if (!$mysqli->query("INSERT INTO events(task) VALUES ('cleanup')")) {
     die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
   }
  }
} else {
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}
if (!$mysqli->query("UPDATE log SET last_update = NOW()")) {
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}
if (!$mysqli->commit()) {
 die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
}

/* 插件判定事务终止,重新启用负载均衡 */
$mysqli->autocommit(TRUE);
$mysqli->close();
?>

Note: 版本需求

trx_stickiness=master 参数需要 PHP 5.4.0 以上版本。

可以参考相关限制在 transaction handling 章节中。

add a note

User Contributed Notes

There are no user contributed notes for this page.

官方地址:https://www.php.net/manual/en/mysqlnd-ms.quickstart.transactions.php

  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net