Skip to content

Instantly share code, notes, and snippets.

@cocoiti
Created December 10, 2014 10:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cocoiti/d82b933f88c17aed28d8 to your computer and use it in GitHub Desktop.
Save cocoiti/d82b933f88c17aed28d8 to your computer and use it in GitHub Desktop.
<?php
namespace XaTestBundle\Doctrine\Connections;
use Doctrine\DBAL\Connection;
use XaTestBundle\Doctrine\TransactionManager;
class TwoPhaseConnection extends Connection
{
protected $transactionManager;
protected $transactinEnd;
private $_towphaceTransactionNestingLevel = 0;
private $xid = null;
public function getTowphaceTransactionNestingLevel()
{
return $this->_towphaceTransactionNestingLevel;
}
public function setTransactionManager(TransactionManager $transactionManager)
{
if ($this->_towphaceTransactionNestingLevel > 0) {
// TODO 例外ちゃんとする
throw new \Exception();
}
$this->transactionManager = $transactionManager;
$this->xid = uniqid(mt_rand());
}
public function getXid()
{
return $this->xid;
}
public function clearTransactionManager()
{
$this->transactionManager = null;
}
/*
* {@inheritDoc}
*/
public function beginTransaction()
{
if (null === $this->transactionManager) {
parent::beginTransaction();
}
if ($this->getTransactionNestingLevel() > 0) {
// すでにトランザクションが事項されていたら例外を出す
// TODO ちゃんとする
throw new \Exception();
}
if ($this->_towphaceTransactionNestingLevel > 0) {
return;
}
$logger = $this->_config->getSQLLogger();
++$this->_towphaceTransactionNestingLevel;
$this->transactinEnd = false;
$this->transactinPrepare = false;
if ($logger) {
$logger->startQuery('"START TWO PHACE TRANSACTION"');
}
// 本来はこのXIDはBINDしたほうがよい
$this->query(sprintf("XA START '%s'", $this->getXid()));
}
/*
* {@inheritDoc}
*/
public function commit()
{
if (null === $this->transactionManager) {
parent::commit();
}
if ($this->_towphaceTransactionNestingLevel > 1) {
return;
}
$logger = $this->_config->getSQLLogger();
if ($logger) {
$logger->startQuery('"COMMIT TWO PHACE TRANSACTION"');
}
// 本来はこのXIDはBINDしたほうがよい
$this->query(sprintf("XA COMMIT '%s'", $this->getXid()));
--$this->_towphaceTransactionNestingLevel;
}
public function prepareTwopahce()
{
$this->doXaEnd();
$logger = $this->_config->getSQLLogger();
if ($logger) {
$logger->startQuery('"PREPARE TWO PHACE TRANSACTION"');
}
// 本来はこのXIDはBINDしたほうがよい
$this->query(sprintf("XA PREPARE '%s'", $this->getXid()));
}
/*
* {@inheritDoc}
*/
public function rollback()
{
if (null === $this->transactionManager) {
parent::rollback();
}
if ($this->_towphaceTransactionNestingLevel > 1) {
return;
}
$this->doXaEnd();
// 本来はこのXIDはBINDしたほうがよい
$this->query(sprintf("XA ROLLBACK '%s'", $this->getXid()));
}
protected function doXaEnd()
{
if (!$this->transactinEnd) {
$this->transactinEnd = true;
$logger = $this->_config->getSQLLogger();
if ($logger) {
$logger->startQuery('"END TWO PHACE TRANSACTION"');
}
$this->query(sprintf("XA END '%s'", $this->getXid()));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment