不少人都说php实现不了分布式事务,java才能实现。事实其实并不是如此。php
事务和数据库有关,和php或者java没有关系 xa事务有2个做用:java
1):支持分布式事务(外部xa)mysql
2): 保持 binlog与innodb的redo log一致性(内部xa) ,事务的实现是基于数据库的。sql
下面看看php如何实现分布式事务。数据库
mysql中的innodb引擎支持xa事务。oracle
可经过如下命令查看innodb是否开启xa事务支持,innodb默认是支持的分布式
要想了解跨数据库事务,必须先搞清楚二阶段提交协议(2pc).ide
下面聊下xa支持跨数据库的分布式事务如何实现sqlserver
条件:多个数据库必须都支持xa事务,mysql的innodb,oracle,sqlserver都支持xaspa
下面直接贴代码:
$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(); }