很多人都说php实现不了分布式事务,java才能实现。事实其实并非如此。
事务和数据库有关,和php或者java没有关系 xa事务有2个作用:
1):支持分布式事务(外部xa)
2): 保持 binlog与innodb的redo log一致性(内部xa) ,事务的实现是基于数据库的。
下面看看php如何实现分布式事务。
mysql中的innodb引擎支持xa事务。
可通过以下命令查看innodb是否开启xa事务支持,innodb默认是支持的
要想了解跨数据库事务,必须先搞清楚二阶段提交协议(2pc).
下面聊下xa支持跨数据库的分布式事务如何实现
条件:多个数据库必须都支持xa事务,mysql的innodb,oracle,sqlserver都支持xa
下面直接贴代码:$mysqlObj1 = new mysqli("10.15.51.78","root","","test")or die("$mysqlObj1 : 连接失败");
$mysqlObj2 = new mysqli("10.15.51.202","root","","test")or die("$mysqlObj2 : 连接失败");
$grid = uniqid("");
$mysqlObj1->query("XA START '$grid'");//准备事务1$mysqlObj2->query("XA START '$grid'");//准备事务2try {
$return = $mysqlObj2->query("UPDATE question SET author='高海峰' WHERE id=10") ;//第一个分支事务准备做的事情,通常他们会记录进日志
if($return == false) {throw new Exception("202数据库更新失败!");
}
$return = $mysqlObj1->query("UPDATE question SET author='高海峰22' WHERE id=11");//第二个分支事务准备做的事情,通常他们会记录进日志
if($return == false) {throw new Exception("78数据库更新失败!");
}
$mysqlObj2->query("XA END '$grid'");
$mysqlObj2->query("XA PREPARE '$grid'");
$mysqlObj1->query("XA END '$grid'");
$mysqlObj1->query("XA PREPARE '$grid'");//通知是否准备提交
$mysqlObj1->query("XA COMMIT '$grid'");//这两个基本同时执行
$mysqlObj2->query("XA COMMIT '$grid'");
} catch (Exception $e) {
$mysqlObj1->query("XA ROLLBACK '$grid'");
$mysqlObj2->query("XA ROLLBACK '$grid'");print $e->getMessage();
}