/***XA MYSQL**/
//连接数据库1
function getConnect1()
{
$con = mysql_connect("localhost","root","root") or die("连接数据库失败1");
mysql_select_db("test1",$con) or die("找不到数据源1");
mysql_query("set names utf-8");
return $con;
}
function closeConnect($con){
if($con){
mysql_close($con);
}
}
//连接数据库2
function getConnect2()
{
$con = mysql_connect("localhost","root","root") or die("连接数据库失败1");
mysql_select_db("test2",$con) or die("找不到数据源2");
mysql_query("set names utf-8");
return $con;
}
$sql ="INSERT INTO `test1`.`help_category` (`help_category_id` ,`name` ,`parent_category_ids` ,`url`)VALUES ('38', 'lfq', '1', '/uuuuullllll');";
$sql2 = "INSERT INTO `test2`.`test` (`id` ,`val`)VALUES (3, 'lfq');";
//准备事务1
function ReadyTransaction1($grid){
$result = mysql_query("XA START '$grid'");
return $result;
}
//准备事务2
function ReadyTransaction2($grid){
$result = mysql_query("XA START '$grid'");
return $result;
}
function getQuery1($sql){
$result = mysql_query($sql);
return $result;
}
function getQuery2($sql){
$r = mysql_query($sql);
return $r;
}
try{
$grid = uniqid("");
$con1 = getConnect1();
ReadyTransaction1($grid);
$r = getQuery1($sql);
if($r == false)
{
throw new Exception("数据1执行失败");
}
$con2 = getConnect2();
ReadyTransaction2($grid);
$r = getQuery2($sql2);
if($r == false){
throw new Exception("数据2执行失败");
}
//通知是否准备提交
getQuery1("XA END '$grid'");
getQuery1("XA PREPARE '$grid'");
getQuery2("XA END '$grid'");
getQuery2("XA PREPARE '$grid'");
getQuery2("XA COMMIT '$grid'");//这两个基本同时执行
getQuery1("XA COMMIT '$grid'");
closeConnect($con1);
closeConnect($con2);
}
catch(Exception $e)
{
getQuery1("XA ROLLBACK '$grid'");
getQuery2("XA ROLLBACK '$grid'");
print $e->getMessage();
}
两阶段说明:
在第一阶段,所有的分支被预备好。即,它们被TM告知要准备提交。通常,这意味着用于管理分支的每个RM会记录对于被稳定保存的分支的行动。分支指示是否它们可以这么做。这些结果被用于第二阶段。
在第二阶段,TM告知RMs是否要提交或 回滚。如果在预备分支时,所有的分支指示它们将能够提交,则所有的分支被告知要提交。如果在预备时,有任何分支指示它将不能提交,则所有分支被告知 回滚。
常见的坑说明:
回滚
a. 如果这个xa事务commit了,那么什么也不用做。
b. 如果这个xa事务还没有prepare,那么直接回滚它。
c. 如果这个xa事务prepare了,还没commit,那么把它恢复到prepare的状态,由用户去决定commit或rollback。
mysql 5.6 分布式事务出现意外情况会丢失prepare binlog,建议使用5.7以上版本
XA事务和本地事务以及锁表操作是互斥的
xa start之后必须xa end,否则不能执行xa commit和xa rollback