分布式事务(多表多库)
2015-11-05 15:16
573 查看
yii下一个分布式事务处理(多表多库)
controller
model
可能出现的问题
问题1.
如何生成事务的唯一xid.
解决方法:
参照mysql xid的手册,写一个生成方法!
问题2.
在window上采用pdo_mysql只能执行一次存储过程,所以更不用说分布事务了.
解决方法:
更换平台在Linux上进行测试,就没问题呢!
问题3:
XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state
分析
1.可能是有隐含事务在前面执行.
2 可能有不支持SQL
解决方法:
1)避免不能在事务里使用的SQL
2)检查涉及表结构不是INNODB
3)检查的存储过程有错误
4)避免接口里数据API是否已经有事务语句执行!
问题4:
失败了,事务不XA ROLLBACK
分析:
程序调用或存储过程编写有问题.
问题5:
事务中单库(多表)只能对应唯一的xid
解决:
1 开启mysql的generalog 迸行察看sql日志.查找调用或存储过程问题.
controller
/** public function actionReview(){ $user=Yii::app()->user; $userid = @$user->user_id; $orderid = Yii::app()->request->getParam('orderid'); $wf_id = Yii::app()->request->getParam('wf_id'); $rebate = Yii::app()->request->getParam('rebate'); $wf = Workflow::model()->findByPk($wf_id); $orderinfo = DOrdersInfo::getOrderInfoId($orderid); if ($orderinfo){ $orders = Orders::model()->find("order_number='".$orderinfo['order_number']."'"); $rebate_total = floatval($orders['contract_price']) * ($rebate/100); } if(Yii::app()->request->getPost('submit')){ $msg = ''; if($orderinfo){ $settle_date = Yii::app()->request->getPost('settle_date'); $settle_date = $settle_date?strtotime($settle_date):time(); $invoice_date = Yii::app()->request->getPost('invoice_date'); $invoice_date = $invoice_date?strtotime($invoice_date):time(); //订 $pagam['settle_state']= Yii::app()->request->getPost('settle'); $pagam['settle_date']= $settle_date; $pagam['related_order_number']=$orderinfo['related_order_number']; //工 $pagam['wf_id']= $wf_id; $pagam['ptime']= date('Y-m-d H:i:s'); $res_m = Workflow::updateInfom($pagam); //更新 //伙 $bills_pagam = array( 'money' => Yii::app()->request->getPost('sales_interest'), 'channel' => $orders['channel_id'], 'order_number' => $orders['order_number'] ); $bills = Workflow::createBills($bills_pagam); //事务处理 if ($res_m['status'] == 'success' && $bills['status'] == 'success'){ Wow::commit_m($res_m['XA']); Wow::commit_n($bills['XA']); }else { Workflow::rollback_m($res_m['XA']); Workflow::rollback_n($bills['XA']); } }else{ $this->renderPartial('/public/error',array('msg'=>'该订不存在')); } $this->renderPartial('/public/success',array('msg'=>'确认成功','goto'=>'/workflow/index?status=0','reload'=>false)); }else{ $this->renderPartial('review',array('orderinfo'=>$orderinfo,'wf_id'=>$wf_id,'rebate'=>$rebate_total)); } }
model
/** * @date: 2015-11-5 * @author: * @desc: */ public static function updateInfom($pagam){ $XA = uniqid(""); Yii::app()->db->createCommand("XA START '".$XA."'")->query(); $_rs = true; try { //更新 $order_sql = "update ordrs set sett_state='".$pagam."',sett_date='".$pagam2."'; $res_order = Yii::app()->db->createCommand($order_sql)->execute(); //关闭 $close_sql = "update workw set operator='".$pagam."',status='".$pagam2."'; $res_close = Yii::app()->db->createCommand($close_sql)->execute(); //工备 $workflow_log = new WorkflowLog(); $workflow_log->wf_id = $wf_id; $res_wflog = $workflow_log->insert(); if (!$res_order && !$res_close && !$res_wflog){ $_rs = false; } }catch (Exception $e){ var_dump($e); $_rs = false; } Yii::app()->db->createCommand("XA END '".$XA."'")->query(); if ($_rs){ Yii::app()->db->createCommand("XA PREPARE '".$XA."'")->query(); return array("status"=>"success","XA"=>$XA); }else { return array("status"=>"nosuccess","XA"=>$XA); } } /** public static function createBills($pagam){ $XA = uniqid(""); bca7 Yii::app()->dbnew->createCommand("XA START '".$XA."'")->query(); $_rs = true; try { $sql = "insert into bills(type,money) values(1,$money)"; $result = Yii::app()->dbnew->createCommand($sql)->execute(); if (!$result){ $_rs = false; } }catch (Exception $e){ var_dump($e); $_rs = false; } Yii::app()->dbnew->createCommand("XA END '".$XA."'")->query(); if ($_rs){ Yii::app()->dbnew->createCommand("XA PREPARE '".$XA."'")->query(); return array("status"=>"success","XA"=>$XA); }else { return array("status"=>"nosuccess","XA"=>$XA); } } /** * @date: 2015-11-4 * @author: * @desc: 事务 */ public static function commit_m($xa){ return Yii::app()->db->createCommand("XA COMMIT '".$xa."'")->query(); } /** * @date: 2015-11-4 * @author: * @desc: 回滚 */ public static function rollback_m($xa){ return Yii::app()->db->createCommand("XA ROLLBACK '".$xa."'")->query(); } /** * @date: 2015-11-4 * @author: * @desc: 事务 */ public static function commit_n($xa){ return Yii::app()->dbnew->createCommand("XA COMMIT '".$xa."'")->query(); } /** * @date: 2015-11-4 * @author: * @desc: 回滚 */ public static function rollback_n($xa){ return Yii::app()->dbnew->createCommand("XA ROLLBACK '".$xa."'")->query(); }
可能出现的问题
问题1.
如何生成事务的唯一xid.
解决方法:
参照mysql xid的手册,写一个生成方法!
问题2.
在window上采用pdo_mysql只能执行一次存储过程,所以更不用说分布事务了.
解决方法:
更换平台在Linux上进行测试,就没问题呢!
问题3:
XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state
分析
1.可能是有隐含事务在前面执行.
2 可能有不支持SQL
解决方法:
1)避免不能在事务里使用的SQL
2)检查涉及表结构不是INNODB
3)检查的存储过程有错误
4)避免接口里数据API是否已经有事务语句执行!
问题4:
失败了,事务不XA ROLLBACK
分析:
程序调用或存储过程编写有问题.
问题5:
事务中单库(多表)只能对应唯一的xid
解决:
1 开启mysql的generalog 迸行察看sql日志.查找调用或存储过程问题.
相关文章推荐
- MySQL分布式事务语句操作
- 如何用消息系统避免分布式事务?
- JTA经典问答
- 如何用消息系统避免分布式事务?
- java基于atomikos做分布式事务(简单实例)
- 分布式事务
- 分布式事务中的两阶段提交
- “分布式事务”的理解(适用于访问多个数据库之间)
- System.Runtime.InteropServices.COMException (0x8004E00F): COM+ 无法与 Microsoft 分布式事务协调程序交谈 (异常来自 HRESU
- [Oracle] 分布式事务和两阶段提交(2PC)
- MySQL数据库分布式事务XA实现原理分析
- MySQL数据库分布式事务XA优缺点与改进方案
- Spring JTA 分布式事务
- 事务(Transaction) 之分布式事务TransactionScope,原子性
- spring+mybatis+atomikos 实现JTA事务
- ASP.NET中分布式事务的使用
- 让我们聊聊Mnesia(一)
- 微服务架构分布式事务解决方案设计思路(可靠消息最终一致方案-设计方案)