트랜잭션은 데이터베이스의 다양한 데이터 항목에 액세스하고 업데이트할 수 있는 프로그램 실행 단위입니다.
트랜잭션에는 원자성, 일관성, 격리성, 지속성
원자성이라는 4가지 속성이 있어야 합니다. 트랜잭션은 분할할 수 없는 작업 단위입니다. 트랜잭션에 포함된 모든 작업은 완료되거나 수행되지 않습니다.
일관성. 트랜잭션은 데이터베이스를 하나의 일관성 상태에서 다른 일관성 상태로 변경해야 합니다. 일관성과 원자성은 밀접한 관련이 있습니다.
격리. 거래의 실행은 다른 거래에 의해 방해받을 수 없습니다. 즉, 트랜잭션 내에서 사용되는 작업과 데이터는 다른 동시 트랜잭션과 격리되며, 동시에 실행되는 트랜잭션은 서로 간섭할 수 없습니다.
내구성. 영속성이라고도 하는 연속성은 트랜잭션이 커밋되면 데이터베이스의 데이터 변경 사항이 영구적이어야 함을 의미합니다. 후속 작업이나 실패는 이에 영향을 미치지 않습니다.
분산 트랜잭션: 분산 트랜잭션의 참여자, 자원 관리자, 트랜잭션 관리자 등은 서로 다른 노드에 위치하며 이러한 서로 다른 노드가 서로 협력하여 논리적 무결성으로 트랜잭션을 완료합니다.
mysql에 대한 오해를 바로잡습니다. Mysql은 5.0부터 XA DataSource를 지원합니다. Connector/J 버전은 5.0 버전을 사용해야 하며, 5.0 미만 버전은 지원하지 않습니다.
XA 프로토콜은 Tuxedo에서 처음 제안되었으며 리소스 관리자(데이터베이스) 및 트랜잭션 관리자를 위한 인터페이스 표준으로 X/Open 조직에 전달되었습니다. 현재 Oracle, Informix, DB2 및 Sybase와 같은 주요 데이터베이스 제조업체는 XA에 대한 지원을 제공합니다. XA 프로토콜은 2단계 커밋 방법을 사용하여 분산 트랜잭션을 관리합니다. XA 인터페이스는 리소스 관리자와 트랜잭션 관리자 간의 통신을 위한 표준 인터페이스를 제공합니다. XA 프로토콜에는 xa_로 시작하는 함수와 ax_로 시작하는 두 가지 함수 집합이 포함되어 있습니다.
다음 함수를 사용하면 트랜잭션 관리자가 리소스 관리자에 대한 작업을 수행할 수 있습니다.
1) xa_open, xa_close: 리소스 관리자와의 연결을 설정하고 닫습니다.
2) xa_start,xa_end: 로컬 트랜잭션을 시작하고 종료합니다.
3) xa_prepare,xa_commit,xa_rollback: 로컬 트랜잭션을 사전 커밋, 커밋 및 롤백합니다.
4) xa_recover: 사전 커밋된 트랜잭션을 롤백합니다.
5) ax_로 시작하는 함수를 사용하면 리소스 관리자가 트랜잭션 관리자에 동적으로 등록하고 XID(TRANSACTION IDS)에 대해 작업할 수 있습니다.
6) ax_reg, ax_unreg; 리소스 관리자가 TMS(TRANSACTION MANAGER SERVER)에 동적으로 등록하거나 등록 취소할 수 있도록 합니다.
Binlog 내부로 binlog에 나타나는 내부 xid인 XA 코디네이터는 응급 복구 중에 binlog에 의해 제출됩니다. (binlog는 준비하지 않고 커밋만 하기 때문에 binlog에 나타나는 내부 xid는 기본 스토리지 엔진에서 준비되었음을 보장해야 합니다.)
MySQL 데이터베이스 외부 XA는 분산 데이터베이스 프록시 계층에서 오픈 소스 프록시 도구(NetEase의 DDB, Taobao의 TDDL, B2B의 Cobar 등)와 같은 MySQL 데이터베이스에 대한 분산 트랜잭션 지원을 구현하는 데 사용할 수 있습니다.
예
public function testAction(){ $goods_id=1; $goods_name = "大西瓜"; $num = 1; $rs_order = $this->test->createorder($goods_id,$goods_name,$num); $rs_goods = $this->test->deduction($goods_id,$num); if($rs_order['status'] =="success" && $rs_goods['status']=="success"){ $this->test->commitdb($rs_order['XA']); $this->test->commitdb1($rs_goods['XA']); }else{ $this->test->rollbackdb($rs_order['XA']); $this->test->rollbackdb1($rs_goods['XA']); } print_r($rs_order); echo "<br />"; print_r($rs_goods); die("dddd"); } public function createorder($goods_id,$goods_name,$num){ $XA = uniqid(""); $this->_db->query("XA START '$XA'"); $_rs = true; try { $data = array(); $data['order_id'] = "V".date("YmdHis"); $data['goods_name'] = $goods_name; $data['goods_num'] = $num; $this->_db->insert("temp_orders",$data); $rs = $this->_db->lastInsertId(); if($rs){ $_rs = true; }else{ $_rs = false; } } catch (Exception $e) { $_rs = false; } $this->_db->query("XA END '$XA'"); if($_rs){ $this->_db->query("XA PREPARE '$XA'"); return array("status"=>"success","XA"=>$XA); }else{ return array("status"=>"nosuccess","XA"=>$XA); } } public function deduction($id){ $XA = uniqid(""); $this->db1->query("XA START '$XA'"); $last_rs = true; try { $sql = "select * from temp_goods where id = '$id' and goods_num>0"; $rs = $this->db1->fetchRow($sql); if(!empty($rs)){ $sql = "update temp_goods set goods_num = goods_num-1 where id = '$id'"; $rd = $this->db1->query($sql); if($rd){ $last_rs = true; }else{ $last_rs = false; } }else{ $last_rs = false;; } } catch (Exception $e) { $last_rs = false;; } $this->db1->query("XA END '$XA'"); if($last_rs){ $this->db1->query("XA PREPARE '$XA'"); return array("status"=>"success","XA"=>$XA); }else{ return array("status"=>"nosuccess","XA"=>$XA); } } //提交事务! public function commitdb($xa){ return $this->_db->query("XA COMMIT '$xa'"); } //回滚事务 public function rollbackdb($xa){ return $this->_db->query("XA ROLLBACK '$xa'"); } //提交事务! public function commitdb1($xa){ return $this->db1->query("XA COMMIT '$xa'"); } //回滚事务 public function rollbackdb1($xa){ return $this->db1->query("XA ROLLBACK '$xa'"); }