php使用xa规范实现分布式事务处理

时间:2022-03-15 23:52:14

具体实例如下,对数据表进行插入和删除操作,两个操作都成功才会修改数据表,否则数据表不变。

<?php
class connDb{
    private static $host = 'jxq-off-ku-qa00.dns.ganji.com:3400';
    private static $username = 'root';
    private static $password = '123456';
    private static $dbName = 'test';
    private $conn = null;

    public function __construct(){
        $this->conn = new MySQLi(self::$host,self::$username,self::$password,self::$dbName);
        if(!$this->conn){
            die('数据库连接错误:'.$this->conn->connect_error);
        }
        $this->conn->query("set names utf-8");
    }

    public function execute_xa($sql){
        $this->conn->query($sql);
    }

    public function execute_dql($sql){
        $rs = $this->conn->query($sql) or die('查询数据库出错:'.$this->conn->error);
        $rsList = array();
        if($rs){
            while($row = $rs->fetch_assoc()){
                $rsList[] = $row;
            }
        }
        $rs->free();
        return $rsList;
    }

    public function execute_dml($sql){
        $rs = $this->conn->query($sql);
        if(!$rs){
            $flag = 0;
            die('数据库操作出错:'.$this->conn->error);
        }else if($this->conn->affected_rows > 0){
            $flag = 1;
        }else{
            $flag = 2;
        }
        return $flag;
    }

    public function closeConn(){
        $this->conn->close();
    }
}

testAction();
function testAction(){
    $XA = uniqid("");
    $conn1 = new connDb();
    $conn2 = new connDb();
    $sql1 = "insert into LiuHuaYongUser (username,password) values('admin3','111111')";
    $sql2 = "delete from LiuHuaYongUser where id = 165";
    $conn1->execute_xa("XA START '$XA'");
    $conn2->execute_xa("XA START '$XA'");
    try{
        $add_status = $conn1->execute_dml($sql1);
        $del_status = $conn1->execute_dml($sql2);

        $conn1->execute_xa("XA END '$XA'");
        $conn2->execute_xa("XA END '$XA'");

        $conn1->execute_xa("XA PREPARE '$XA'");
        $conn2->execute_xa("XA PREPARE '$XA'");

        if(!($add_status && $del_status)){
            throw new Exception("操作失败");
        }

        echo '程序运行成功!';
        $conn1->execute_xa("XA COMMIT '$XA'");
        $conn2->execute_xa("XA COMMIT '$XA'");
    }catch (Exception $ex){
        echo '程序运行失败!';
        $conn1->execute_xa("XA ROLLBACK '$XA'");
        $conn2->execute_xa("XA ROLLBACK '$XA'");
    }


}



?>