/** * Summary of __construct * @param mixed $Sane * @param DatabaseTransactionScopeOption $ScopeOption * @param DatabaseTransactionIsolationLevel $IsolationLevel */ public function __construct($Sane = FALSE, DatabaseTransactionScopeOption $ScopeOption = NULL, DatabaseTransactionIsolationLevel $IsolationLevel = NULL) { $this->_Sane = $Sane; if ($ScopeOption == NULL) { $ScopeOption = DatabaseTransactionScopeOption::RequiresNew(); } if ($IsolationLevel == NULL) { $IsolationLevel = DatabaseTransactionIsolationLevel::Unspecified(); } $this->_IsolationLevel = $IsolationLevel; $this->_ScopeOption = $ScopeOption; }
/** * Summary of pushTransaction * @param string $name * @param DatabaseTransactionSettings $settings * @throws DatabaseTransactionNameNonUniqueException * @return void */ public function pushTransaction($name, $settings = NULL) { if ($settings == NULL) { $settings = DatabaseTransactionSettings::GetBetterDefaults(); } if (!$this->supportsTransactions()) { return; } if (isset($this->transactionLayers[$name])) { throw new DatabaseTransactionNameNonUniqueException($name . " is already in use."); } $started = FALSE; // If we're already in a transaction. // TODO: Transaction scope Options is not working properly // for first level transactions. It assumes that - always - a first level // transaction must be started. if ($this->inTransaction()) { switch ($settings->Get_ScopeOption()) { case DatabaseTransactionScopeOption::RequiresNew(): $this->query_direct('SAVE TRANSACTION ' . $name); $started = TRUE; break; case DatabaseTransactionScopeOption::Required(): // We are already in a transaction, do nothing. break; case DatabaseTransactionScopeOption::Supress(): // The only way to supress the ambient transaction is to use a new connection // during the scope of this transaction, a bit messy to implement. throw new Exception('DatabaseTransactionScopeOption::Supress not implemented.'); } } else { if ($settings->Get_IsolationLevel() != DatabaseTransactionIsolationLevel::Ignore()) { $current_isolation_level = strtoupper($this->schema()->UserOptions()['isolation level']); // Se what isolation level was requested. $level = $settings->Get_IsolationLevel()->__toString(); if (strcasecmp($current_isolation_level, $level) !== 0) { $this->query_direct("SET TRANSACTION ISOLATION LEVEL {$level}"); } } // In order to start a transaction current statement cursors // must be closed. foreach($this->statement_cache as $statement) { $statement->closeCursor(); } $this->connection->beginTransaction(); } // Store the name and settings in the stack. $this->transactionLayers[$name] = array('settings' => $settings, 'active' => TRUE, 'name' => $name, 'started' => $started); }