Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
<?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
You can’t perform that action at this time.