You are here

public function DatabaseConnection_sqlsrv::pushTransaction in Drupal driver for SQL Server and SQL Azure 7.3

Same name and namespace in other branches
  1. 7.2 sqlsrv/database.inc \DatabaseConnection_sqlsrv::pushTransaction()

Summary of pushTransaction

Parameters

string $name:

DatabaseTransactionSettings $settings:

Return value

void

Throws

DatabaseTransactionNameNonUniqueException

Overrides DatabaseConnection::pushTransaction

File

sqlsrv/database.inc, line 805
Database interface code for Microsoft SQL Server.

Class

DatabaseConnection_sqlsrv
Summary of DatabaseConnection_sqlsrv

Code

public function pushTransaction($name, $settings = NULL) {
  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()) {
      $user_options = $this
        ->schema()
        ->UserOptions();
      $current_isolation_level = strtoupper($user_options['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,
  );
}