diff --git a/core/lib/Drupal/Core/Session/SessionHandler.php b/core/lib/Drupal/Core/Session/SessionHandler.php
index c8d69fb..1075900 100644
--- a/core/lib/Drupal/Core/Session/SessionHandler.php
+++ b/core/lib/Drupal/Core/Session/SessionHandler.php
@@ -152,12 +152,6 @@ public function write($sid, $value) {
     // The exception handler is not active at this point, so we need to do it
     // manually.
     try {
-      if (!$this->sessionManager->isEnabled()) {
-        // We don't have anything to do if we are not allowed to save the
-        // session.
-        return TRUE;
-      }
-
       // Either ssid or sid or both will be added from $key below.
       $fields = array(
         'uid' => $user->id(),
@@ -227,10 +221,6 @@ public function close() {
   public function destroy($sid) {
     global $user;
 
-    // Nothing to do if we are not allowed to change the session.
-    if (!$this->sessionManager->isEnabled()) {
-      return TRUE;
-    }
     $is_https = $this->requestStack->getCurrentRequest()->isSecure();
     // Delete session data.
     $this->connection->delete('sessions')
diff --git a/core/lib/Drupal/Core/Session/SessionManager.php b/core/lib/Drupal/Core/Session/SessionManager.php
index b0fcc33..5cd7a20 100644
--- a/core/lib/Drupal/Core/Session/SessionManager.php
+++ b/core/lib/Drupal/Core/Session/SessionManager.php
@@ -65,15 +65,15 @@ class SessionManager extends NativeSessionStorage implements SessionManagerInter
   protected $startedLazy;
 
   /**
-   * Whether session management is enabled or temporarily disabled.
+   * The write barrier session handler.
    *
-   * PHP session ID, session, and cookie handling happens in the global scope.
-   * This value has to persist, since a potentially wrong or disallowed session
-   * would be written otherwise.
+   * @todo: The write barrier session handler should be exposed in the
+   *   container and this reference should be removed once all database queries
+   *   are removed from the session manager class.
    *
-   * @var bool
+   * @var \Drupal\Core\Session\WriteBarrierSessionHandler
    */
-  protected static $enabled = TRUE;
+  protected $writeBarrierHandler;
 
   /**
    * Constructs a new session manager instance.
@@ -96,9 +96,9 @@ public function __construct(RequestStack $request_stack, Connection $connection,
     // @todo Extract session storage from session handler into a service.
     $save_handler = new SessionHandler($this, $this->requestStack, $this->connection);
     $write_check_handler = new WriteCheckSessionHandler($save_handler);
-    $this->setSaveHandler($write_check_handler);
+    $this->writeBarrierHandler = new WriteBarrierSessionHandler($write_check_handler);
 
-    parent::__construct($options, $write_check_handler, $metadata_bag);
+    parent::__construct($options, $this->writeBarrierHandler, $metadata_bag);
 
     $this->setMixedMode($settings->get('mixed_mode_sessions', FALSE));
 
@@ -165,7 +165,7 @@ public function isStartedLazy() {
    * {@inheritdoc}
    */
   public function start() {
-    if (!$this->isEnabled() || $this->isCli()) {
+    if ($this->isCli()) {
       return;
     }
     // Save current session data before starting it, as PHP will destroy it.
@@ -187,7 +187,7 @@ public function start() {
   public function save() {
     global $user;
 
-    if (!$this->isEnabled() || $this->isCli()) {
+    if ($this->isCli()) {
       // We don't have anything to do if we are not allowed to save the session.
       return;
     }
@@ -226,7 +226,7 @@ public function regenerate($destroy = FALSE, $lifetime = NULL) {
     global $user;
 
     // Nothing to do if we are not allowed to change the session.
-    if (!$this->isEnabled() || $this->isCli()) {
+    if ($this->isCli()) {
       return;
     }
 
@@ -271,10 +271,12 @@ public function regenerate($destroy = FALSE, $lifetime = NULL) {
           $fields['sid'] = Crypt::hashBase64($session_id);
         }
       }
-      $this->connection->update('sessions')
-        ->fields($fields)
-        ->condition($is_https ? 'ssid' : 'sid', Crypt::hashBase64($old_session_id))
-        ->execute();
+      if ($this->writeBarrierHandler->isSessionWritable()) {
+        $this->connection->update('sessions')
+          ->fields($fields)
+          ->condition($is_https ? 'ssid' : 'sid', Crypt::hashBase64($old_session_id))
+          ->execute();
+      }
     }
 
     if (!$this->isStarted()) {
@@ -293,7 +295,7 @@ public function regenerate($destroy = FALSE, $lifetime = NULL) {
    */
   public function delete($uid) {
     // Nothing to do if we are not allowed to change the session.
-    if (!$this->isEnabled() || $this->isCli()) {
+    if (!$this->writeBarrierHandler->isSessionWritable() || $this->isCli()) {
       return;
     }
     $this->connection->delete('sessions')
@@ -305,14 +307,14 @@ public function delete($uid) {
    * {@inheritdoc}
    */
   public function isEnabled() {
-    return static::$enabled;
+    return $this->writeBarrierHandler->isSessionWritable();
   }
 
   /**
    * {@inheritdoc}
    */
   public function disable() {
-    static::$enabled = FALSE;
+    $this->writeBarrierHandler->setSessionWritable(FALSE);
     return $this;
   }
 
@@ -320,7 +322,7 @@ public function disable() {
    * {@inheritdoc}
    */
   public function enable() {
-    static::$enabled = TRUE;
+    $this->writeBarrierHandler->setSessionWritable(TRUE);
     return $this;
   }
 
diff --git a/core/lib/Drupal/Core/Session/WriteBarrierSessionHandler.php b/core/lib/Drupal/Core/Session/WriteBarrierSessionHandler.php
new file mode 100644
index 0000000..18ba432
--- /dev/null
+++ b/core/lib/Drupal/Core/Session/WriteBarrierSessionHandler.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\Core\Session\WriteBarrierSessionHandler.
+ */
+
+namespace Drupal\Core\Session;
+
+/**
+ * Wraps another SessionHandlerInterface to prevent writes during dangerous operations.
+ */
+class WriteBarrierSessionHandler implements \SessionHandlerInterface {
+
+  /**
+   * @var \SessionHandlerInterface
+   */
+  private $wrappedSessionHandler;
+
+  /**
+   * Whether or not the write barrier is enabled.
+   *
+   * @var bool
+   */
+  private $sessionWritable;
+
+  /**
+   * Constructs a new write barrier session handler.
+   *
+   * @param \SessionHandlerInterface $wrapped_session_handler
+   *   The underlying session handler.
+   * @param bool $session_writable
+   *   Whether or not the session should be initially writable.
+   */
+  public function __construct(\SessionHandlerInterface $wrapped_session_handler, $session_writable = TRUE) {
+    $this->wrappedSessionHandler = $wrapped_session_handler;
+    $this->sessionWritable = $session_writable;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function close() {
+    return $this->wrappedSessionHandler->close();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function destroy($session_id) {
+    return $this->wrappedSessionHandler->destroy($session_id);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function gc($max_lifetime) {
+    return $this->wrappedSessionHandler->gc($max_lifetime);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function open($save_path, $session_id) {
+    return $this->wrappedSessionHandler->open($save_path, $session_id);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function read($session_id) {
+    return $this->wrappedSessionHandler->read($session_id);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function write($session_id, $session_data) {
+    if ($this->isSessionWritable()) {
+      return $this->wrappedSessionHandler->write($session_id, $session_data);
+    }
+    else {
+      return TRUE;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setSessionWritable($flag) {
+    $this->sessionWritable = (bool) $flag;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isSessionWritable() {
+    return $this->sessionWritable;
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Session/WriteBarrierSessionHandlerTest.php b/core/tests/Drupal/Tests/Core/Session/WriteBarrierSessionHandlerTest.php
new file mode 100644
index 0000000..58cb267
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Session/WriteBarrierSessionHandlerTest.php
@@ -0,0 +1,180 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\Session\WriteBarrierSessionHandlerTest.
+ */
+
+namespace Drupal\Tests\Core\Session;
+
+use Drupal\Tests\UnitTestCase;
+use Drupal\Core\Session\WriteBarrierSessionHandler;
+
+/**
+ * @coversDefaultClass \Drupal\Core\Session\WriteBarrierSessionHandler
+ * @group Session
+ */
+class WriteBarrierSessionHandlerTest extends UnitTestCase {
+
+  /**
+   * The wrapped session handler.
+   *
+   * @var \SessionHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $wrappedSessionHandler;
+
+  /**
+   * The write barrier session handler.
+   *
+   * @var \Drupal\Core\Session\WriteBarrierSessionHandler
+   */
+  protected $sessionHandler;
+
+  public function setUp() {
+    $this->wrappedSessionHandler = $this->getMock('SessionHandlerInterface');
+    $this->sessionHandler = new WriteBarrierSessionHandler($this->wrappedSessionHandler);
+  }
+
+  /**
+   * Tests creating an WriteBarrierSessionHandler with default arguments.
+   *
+   * @covers ::__construct
+   * @covers ::isSessionWritable
+   * @covers ::write
+   */
+  public function testConstructWriteBarrierSessionHandlerDefaultArgs() {
+    $session_id = 'some-id';
+    $session_data = 'serialized-session-data';
+
+    $this->assertSame($this->sessionHandler->isSessionWritable(), TRUE);
+
+    // Writing should be enabled, return value passed to the caller by default.
+    $this->wrappedSessionHandler->expects($this->at(0))
+      ->method('write')
+      ->with($session_id, $session_data)
+      ->will($this->returnValue(TRUE));
+
+    $this->wrappedSessionHandler->expects($this->at(1))
+      ->method('write')
+      ->with($session_id, $session_data)
+      ->will($this->returnValue(FALSE));
+
+    $result = $this->sessionHandler->write($session_id, $session_data);
+    $this->assertSame($result, TRUE);
+
+    $result = $this->sessionHandler->write($session_id, $session_data);
+    $this->assertSame($result, FALSE);
+  }
+
+  /**
+   * Tests creating an WriteBarrierSessionHandler with session writing disabled.
+   *
+   * @covers ::__construct
+   * @covers ::isSessionWritable
+   * @covers ::write
+   */
+  public function testConstructWriteBarrierSessionHandlerDisableWriting() {
+    $session_id = 'some-id';
+    $session_data = 'serialized-session-data';
+
+    // Disable writing upon construction.
+    $this->sessionHandler = new WriteBarrierSessionHandler($this->wrappedSessionHandler, FALSE);
+
+    $this->assertSame($this->sessionHandler->isSessionWritable(), FALSE);
+
+    $result = $this->sessionHandler->write($session_id, $session_data);
+    $this->assertSame($result, TRUE);
+  }
+
+  /**
+   * Tests using setSessionWritable to enable/disable session writing.
+   *
+   * @covers ::setSessionWritable
+   * @covers ::write
+   */
+  public function testSetSessionWritable() {
+    $session_id = 'some-id';
+    $session_data = 'serialized-session-data';
+
+    $this->assertSame($this->sessionHandler->isSessionWritable(), TRUE);
+
+    // Disable writing after construction.
+    $this->sessionHandler->setSessionWritable(FALSE);
+    $this->assertSame($this->sessionHandler->isSessionWritable(), FALSE);
+
+    $this->sessionHandler = new WriteBarrierSessionHandler($this->wrappedSessionHandler, FALSE);
+
+    $this->assertSame($this->sessionHandler->isSessionWritable(), FALSE);
+
+    $result = $this->sessionHandler->write($session_id, $session_data);
+    $this->assertSame($result, TRUE);
+
+    // Enable writing again.
+    $this->sessionHandler->setSessionWritable(TRUE);
+    $this->assertSame($this->sessionHandler->isSessionWritable(), TRUE);
+
+    // Writing should be enabled, return value passed to the caller by default.
+    $this->wrappedSessionHandler->expects($this->at(0))
+      ->method('write')
+      ->with($session_id, $session_data)
+      ->will($this->returnValue(TRUE));
+
+    $this->wrappedSessionHandler->expects($this->at(1))
+      ->method('write')
+      ->with($session_id, $session_data)
+      ->will($this->returnValue(FALSE));
+
+    $result = $this->sessionHandler->write($session_id, $session_data);
+    $this->assertSame($result, TRUE);
+
+    $result = $this->sessionHandler->write($session_id, $session_data);
+    $this->assertSame($result, FALSE);
+  }
+
+  /**
+   * Tests that other invocations are passed unmodified to the wrapped handler.
+   *
+   * @covers ::setSessionWritable
+   * @covers ::open
+   * @covers ::read
+   * @covers ::close
+   * @covers ::destroy
+   * @covers ::gc
+   * @dataProvider providerTestOtherMethods
+   */
+  public function testOtherMethods($method, $expected_result, $args) {
+    $invocation = $this->wrappedSessionHandler->expects($this->exactly(2))
+      ->method($method)
+      ->will($this->returnValue($expected_result));
+
+    // Set the parameter matcher.
+    call_user_func_array([$invocation, 'with'], $args);
+
+    // Test with writable session.
+    $this->assertSame($this->sessionHandler->isSessionWritable(), TRUE);
+    $actual_result = call_user_func_array([$this->sessionHandler, $method], $args);
+    $this->assertSame($expected_result, $actual_result);
+
+    // Test with non-writable session.
+    $this->sessionHandler->setSessionWritable(FALSE);
+    $this->assertSame($this->sessionHandler->isSessionWritable(), FALSE);
+    $actual_result = call_user_func_array([$this->sessionHandler, $method], $args);
+    $this->assertSame($expected_result, $actual_result);
+  }
+
+  /**
+   * Provides test data for the other methods test.
+   *
+   * @return array
+   *   Test data.
+   */
+  public function providerTestOtherMethods() {
+    return [
+      ['open', TRUE, ['/some/path', 'some-session-id']],
+      ['read', 'some-session-data', ['a-session-id']],
+      ['close', TRUE, []],
+      ['destroy', TRUE, ['old-session-id']],
+      ['gc', TRUE, [42]],
+    ];
+  }
+}
