トランザクションは、データベース内のさまざまなデータ項目にアクセスし、更新するプログラム実行ユニットです。
トランザクションには、アトミック性、一貫性、分離性、永続性
アトミック性の 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_ で始まる関数の 2 つのセットが含まれています。
次の関数により、トランザクションマネージャーはリソースマネージャーに対して操作を実行できます:
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) に動的に登録または登録解除できます。
MySQL XA は、内部 XA と外部 XA の 2 つのカテゴリに分類されます。内部 XA は、コーディネーターとしておなじみの Binlog を使用して、同じインスタンス内の複数のエンジンにわたるトランザクションに使用されます。アプリケーション層はコーディネーターとして介入する必要があります (クラッシュ、グローバルコミットまたはロールバック中のトランザクションの中断はアプリケーション層によって決定される必要があり、アプリケーション層の実装要件はより高くなります)。
Binlog はコーディネーターとして機能します。 binlog 内の内部 XA 表示される内部 xid は、クラッシュ リカバリ中に binlog によって送信されます。 (これは、バイナリログは準備を行わず、コミットのみを行うためです。そのため、バイナリログに表示される内部 xid は、基礎となるストレージ エンジンで準備されていることが保証されている必要があります)。
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'"); }