事务该当具有4个属性:原子性、同等性、隔离性、持续性
原子性(atomicity)。一个事务是一个不可分割的事情单位,事务中包括的诸操作要么都做,要么都不做。
同等性(consistency)。事务必须是使数据库从一个同等性状态变到另一个同等性状态。同等性与原子性是密切干系的。
隔离性(isolation)。一个事务的实行不能被其他事务滋扰。即一个事务内部的操作及利用的数据对并发的其他事务是隔离的,并发实行的各个事务之间不能相互关扰。
持久性(durability)。持续性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就该当是永久性的。接下来的其他操作或故障不应该对其有任何影响。
分布式事务:分布式事务的参与者、资源管理器、事务管理器等位于不用的节点上,这些不同的节点相互协作共同完成一个具有逻辑完全性的事务。
纠正自己对mysql的一个误解,mysql从5.0开始支持XA DataSource。Connector/J 版本要利用5.0版本,5.0以下的不支持。
XA协议由Tuxedo首先提出的,并交给X/Open组织,作为资源管理器(数据库)与事务管理器的接口标准。目前,Oracle、Informix、DB2和Sybase等各大数据库厂家都供应对XA的支持。XA协议采取两阶段提交办法来管理分布式事务。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)中动态注册或撤消注册。
MySQL XA分为两类,内部XA与外部XA;内部XA用于同一实例下跨多个引擎的事务,由大家熟习的Binlog作为折衷者;外部XA用于跨多MySQL实例的分 布式事务,须要运用层参与作为折衷者(崩溃时的悬挂事务,全局提交还是回滚,须要由运用层决定,对运用层的实现哀求较高);
Binlog作为内部XA的折衷者,在binlog中涌现的内部xid,在crash recover时,由binlog卖力提交。(这是由于,binlog不进行prepare, 只进行commit,因此在binlog中涌现的内部xid,一定能够担保其在底层各存储引擎中已经完成prepare)。
MySQL数据库外部XA可以用在分布式数据库代理层,实现对MySQL数据库的分布式事务支持,例如开源的代理工具:网易的DDB,淘宝的TDDL,B2B的Cobar等等。
示例
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'\"大众); }
点击理解更多去学习:非常利用的代码优化,怎么才能写好代码