TCC是現在非常流行分散式處理模式,屬於柔性事務。柔性事務,基於分散式領域BASE理論,它是在CAP理論(一致性、可用性、分割槽容忍性)的基礎之上的延伸,包括:基本可用(Basically Available)、柔性狀態(Soft State)、最終一致性(Eventual Consistency)。
* 基本可用:分散式系統出現故障的時候,允許損失一部分可用性。
* 柔性狀態:允許系統存在中間狀態,這個中間狀態又不會影響系統整體可用性。
* 最終一致性:資料經過重試等機制處理後,最終資料能達到一致。
處理方式
兩階段提
交事務補償型
最大努力型
laravel 分散式事務處理 - 2PC 兩階段
事務管理器:
/**
* 分散式事務處理
* @param $xids
*/
public function XAProcess($xids)
{
try {
$status = array();
foreach ($xids as $xid) {
$status[$xid] = false;
$translog = TransLog::where('xid',$xid)->get();
try {
foreach ($translog as $item) {
$this->pdo->$xid->query($item->sql);
Log::info("Transaction SQL:".json_encode($item->sql));
}
$status[$xid] = true;
} catch (\Exception $e) {
$status[$xid] = false;
}
}
if (!in_array(false,array_values($status))) {
$this->Commit($xids);
Log::info('transaction committed');
} else {
$this->Rollback($xids);
Log::info('transaction rollback');
}
} catch (\Exception $e) {
$this->Rollback($xids);
Log::info('transaction rollback:'.$e->getMessage());
}
}
/**
* 事務提交
* @param $xids
*/
public function Commit($xids)
{
$this->XAEnd($xids);
$this->XAPrepare($xids);
$this->XACommit($xids);
}
/**
* 事務回滾
* @param $xids
*/
public function RollBack($xids)
{
$this->XAEnd($xids);
$this->XAPrepare($xids);
$this->XARollback($xids);
}
/**
* 事務開始
* @param $xids
*/
public function XAStart($xids)
{
foreach ($xids as $xid) {
$this->pdo->$xid = $this->getPdo('mysql');
$this->pdo->$xid->exec("XA START '$xid'");
}
}
/**
* 事務結束
* @param $xids
*/
public function XAEnd($xids)
{
foreach ($xids as $xid) {
$this->pdo->$xid->exec("XA END '$xid'");
}
}
/**
* 事務預處理
* @param $xids
*/
public function XAPrepare($xids)
{
foreach ($xids as $xid) {
$this->pdo->$xid->exec("XA PREPARE '$xid'");
}
}
/**
* 事務提交
* @param $xids
*/
public function XACommit($xids)
{
foreach ($xids as $xid) {
$this->pdo->$xid->exec("XA COMMIT '$xid'");
}
}
/**
* 事務回滾
* @param $xids
*/
public function XARollback($xids)
{
foreach ($xids as $xid) {
$this->pdo->$xid->exec("XA ROLLBACK '$xid'");
}
}
/**
* 執行sql
* @param $sql
*/
public function XAQuery($sql)
{
$this->pdo->query($sql);
}