mirror of
https://gitlab.com/hashborgir/d2tools.git
synced 2025-04-27 14:55:38 +00:00
91 lines
2.4 KiB
PHP
91 lines
2.4 KiB
PHP
<?php
|
|
|
|
namespace RedBeanPHP\Util;
|
|
|
|
use RedBeanPHP\OODB as OODB;
|
|
use RedBeanPHP\OODBBean as OODBBean;
|
|
use RedBeanPHP\RedException as RedException;
|
|
use RedBeanPHP\Adapter as Adapter;
|
|
|
|
/**
|
|
* Transaction Helper
|
|
*
|
|
* This code was originally part of the facade, however it has
|
|
* been decided to remove unique features to service classes like
|
|
* this to make them available to developers not using the facade class.
|
|
*
|
|
* Database transaction helper. This is a convenience class
|
|
* to perform a callback in a database transaction. This class
|
|
* contains a method to wrap your callback in a transaction.
|
|
*
|
|
* @file RedBeanPHP/Util/Transaction.php
|
|
* @author Gabor de Mooij and the RedBeanPHP Community
|
|
* @license BSD/GPLv2
|
|
*
|
|
* @copyright
|
|
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
|
|
* This source file is subject to the BSD/GPLv2 License that is bundled
|
|
* with this source code in the file license.txt.
|
|
*/
|
|
class Transaction
|
|
{
|
|
/**
|
|
* Wraps a transaction around a closure or string callback.
|
|
* If an Exception is thrown inside, the operation is automatically rolled back.
|
|
* If no Exception happens, it commits automatically.
|
|
* It also supports (simulated) nested transactions (that is useful when
|
|
* you have many methods that needs transactions but are unaware of
|
|
* each other).
|
|
*
|
|
* Example:
|
|
*
|
|
* <code>
|
|
* $from = 1;
|
|
* $to = 2;
|
|
* $amount = 300;
|
|
*
|
|
* R::transaction(function() use($from, $to, $amount)
|
|
* {
|
|
* $accountFrom = R::load('account', $from);
|
|
* $accountTo = R::load('account', $to);
|
|
* $accountFrom->money -= $amount;
|
|
* $accountTo->money += $amount;
|
|
* R::store($accountFrom);
|
|
* R::store($accountTo);
|
|
* });
|
|
* </code>
|
|
*
|
|
* @param Adapter $adapter Database Adapter providing transaction mechanisms.
|
|
* @param callable $callback Closure (or other callable) with the transaction logic
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public static function transaction( Adapter $adapter, $callback )
|
|
{
|
|
if ( !is_callable( $callback ) ) {
|
|
throw new RedException( 'R::transaction needs a valid callback.' );
|
|
}
|
|
|
|
static $depth = 0;
|
|
$result = null;
|
|
try {
|
|
if ( $depth == 0 ) {
|
|
$adapter->startTransaction();
|
|
}
|
|
$depth++;
|
|
$result = call_user_func( $callback ); //maintain 5.2 compatibility
|
|
$depth--;
|
|
if ( $depth == 0 ) {
|
|
$adapter->commit();
|
|
}
|
|
} catch ( \Exception $exception ) {
|
|
$depth--;
|
|
if ( $depth == 0 ) {
|
|
$adapter->rollback();
|
|
}
|
|
throw $exception;
|
|
}
|
|
return $result;
|
|
}
|
|
}
|