mysql 事务 php_PHP: 事务 - Manual

事务

当前版本的插件并不是事务安全的,因为他并没有识别全部的事务操作。

SQL 事务单元是在单一服务器中运行的。插件并不能有效的知道事务单元

何时开始,何时终止。所以,在事务单元中,可能数据库连接会被切换。

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

可以通过 SQL hints 来解除这个限制。可以选择性的调用事务 API 进行监控,

然后嗲用 API 执行控制事务。下面给出范例:

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

[myapp]

{

"myapp": {

"master": {

"master_0": {

"host": "localhost",

"socket": "\/tmp\/mysql.sock"

}

},

"slave": {

"slave_0": {

"host": "192.168.2.27",

"port": "3306"

}

}

}

}

示例 #2 在事务中使用 SQL hints

$mysqli= newmysqli("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 版本后,这种检查将不仅仅检查

mysql_commit() 和

mysql_rollback()。

示例 #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"

}

}

示例 #4 Transaction aware

$mysqli= newmysqli("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();?>

注意:

版本需求

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值