您的位置:首页 > 其它

分布式事务(多表多库)

2015-11-05 15:16 573 查看
yii下一个分布式事务处理(多表多库)

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日志.查找调用或存储过程问题.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息