Skip to content

Commit

Permalink
added transaction helper
Browse files Browse the repository at this point in the history
  • Loading branch information
thinkingmedia committed Nov 18, 2016
1 parent 72d3d29 commit 078f675
Showing 1 changed file with 40 additions and 32 deletions.
72 changes: 40 additions & 32 deletions src/ORM/Table.php
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
use Cake\ORM\Exception\RolledbackTransactionException; use Cake\ORM\Exception\RolledbackTransactionException;
use Cake\ORM\Rule\IsUnique; use Cake\ORM\Rule\IsUnique;
use Cake\Utility\Inflector; use Cake\Utility\Inflector;
use Cake\Validation\Validation;
use Cake\Validation\ValidatorAwareTrait; use Cake\Validation\ValidatorAwareTrait;
use InvalidArgumentException; use InvalidArgumentException;
use RuntimeException; use RuntimeException;
Expand Down Expand Up @@ -1435,6 +1434,36 @@ public function get($primaryKey, $options = [])
return $query->firstOrFail(); return $query->firstOrFail();
} }


/**
* Handles the logic executing of a worker inside a transaction.
*
* @param bool $atomic Whether to execute the worker inside a database transaction.
* @param callable $worker The worker that will run inside the transaction.
* @return mixed
*/
protected function _executeTransaction($atomic, callable $worker)
{
if ($atomic) {
return $this->connection()->transactional(function () use ($worker) {
return call_user_func($worker);
});
}

return call_user_func($worker);
}

/**
* Checks if the caller would have executed a commit on a transaction.
*
* @param bool $atomic True if an atomic transaction was used.
* @param bool $primary True if a primary was used.
* @return bool Returns true if a transaction was committed.
*/
protected function _getCommitUsed($atomic, $primary)
{
return !$this->connection()->inTransaction() && ($atomic || (!$atomic && $primary));
}

/** /**
* Finds an existing record or creates a new one. * Finds an existing record or creates a new one.
* *
Expand Down Expand Up @@ -1475,13 +1504,9 @@ public function findOrCreate($search, callable $callback = null, $options = [])
'defaults' => true 'defaults' => true
]; ];


if ($options['atomic']) { return $this->_executeTransaction($options['atomic'], function () use ($search, $callback, $options) {
return $this->connection()->transactional(function () use ($search, $callback, $options) { return $this->_processFindOrCreate($search, $callback, $options);
return $this->_processFindOrCreate($search, $callback, $options); });
});
}

return $this->_processFindOrCreate($search, $callback, $options);
} }


/** /**
Expand Down Expand Up @@ -1696,19 +1721,12 @@ public function save(EntityInterface $entity, $options = [])
return $entity; return $entity;
} }


$connection = $this->connection(); $success = $this->_executeTransaction($options['atomic'], function () use ($entity, $options) {
if ($options['atomic']) { return $this->_processSave($entity, $options);
$success = $connection->transactional(function () use ($entity, $options) { });
return $this->_processSave($entity, $options);
});
} else {
$success = $this->_processSave($entity, $options);
}


if ($success) { if ($success) {
if (!$connection->inTransaction() && if ($this->_getCommitUsed($options['atomic'], $options['_primary'])) {
($options['atomic'] || (!$options['atomic'] && $options['_primary']))
) {
$this->dispatchEvent('Model.afterSaveCommit', compact('entity', 'options')); $this->dispatchEvent('Model.afterSaveCommit', compact('entity', 'options'));
} }
if ($options['atomic'] || $options['_primary']) { if ($options['atomic'] || $options['_primary']) {
Expand Down Expand Up @@ -2033,21 +2051,11 @@ public function delete(EntityInterface $entity, $options = [])
'_primary' => true, '_primary' => true,
]); ]);


$process = function () use ($entity, $options) { $success = $this->_executeTransaction($options['atomic'], function () use ($entity, $options) {
return $this->_processDelete($entity, $options); return $this->_processDelete($entity, $options);
}; });

$connection = $this->connection();
if ($options['atomic']) {
$success = $connection->transactional($process);
} else {
$success = $process();
}


if ($success && if ($success && $this->_getCommitUsed($options['atomic'], $options['_primary'])) {
!$connection->inTransaction() &&
($options['atomic'] || (!$options['atomic'] && $options['_primary']))
) {
$this->dispatchEvent('Model.afterDeleteCommit', [ $this->dispatchEvent('Model.afterDeleteCommit', [
'entity' => $entity, 'entity' => $entity,
'options' => $options 'options' => $options
Expand Down

0 comments on commit 078f675

Please sign in to comment.