/** * Snapshot isolation is not compatible with DDL operations. * * @return TransactionSettings */ public static function GetDDLCompatibleDefaults() { return new TransactionSettings(TRUE, DatabaseTransactionScopeOption::Required(), DatabaseTransactionIsolationLevel::ReadCommitted()); }
/** * 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); }