Browse Source

Fix a couple of corner cases for Predis\MultiExecBlock.

Daniele Alessandri 14 năm trước cách đây
mục cha
commit
18b44fae53
2 tập tin đã thay đổi với 19 bổ sung8 xóa
  1. 3 0
      CHANGELOG
  2. 16 8
      lib/Predis.php

+ 3 - 0
CHANGELOG

@@ -13,6 +13,9 @@ v0.6.6 (2011-xx-xx)
     to disable read and write timeouts on connections. The old behaviour of -1 
     is still intact.
 
+  * FIX: some client-side clean-ups for MULTI/EXEC were handled incorrectly in 
+    a couple of corner cases.
+
 v0.6.5 (2011-02-12)
   * FIX: due to an untested internal change introduced in v0.6.4, a wrong 
     handling of bulk reads of zero-length values was producing protocol 

+ 16 - 8
lib/Predis.php

@@ -828,7 +828,7 @@ class CommandPipeline {
 }
 
 class MultiExecBlock {
-    private $_initialized, $_discarded, $_insideBlock, $_checkAndSet;
+    private $_initialized, $_discarded, $_insideBlock, $_checkAndSet, $_watchedKeys;
     private $_redisClient, $_options, $_commands;
     private $_supportsWatch;
 
@@ -867,6 +867,7 @@ class MultiExecBlock {
         $this->_discarded   = false;
         $this->_checkAndSet = false;
         $this->_insideBlock = false;
+        $this->_watchedKeys = false;
         $this->_commands    = array();
     }
 
@@ -911,6 +912,7 @@ class MultiExecBlock {
         if ($this->_initialized && !$this->_checkAndSet) {
             throw new ClientException('WATCH inside MULTI is not allowed');
         }
+        $this->_watchedKeys = true;
         return $this->_redisClient->watch($keys);
     }
 
@@ -926,14 +928,17 @@ class MultiExecBlock {
 
     public function unwatch() {
         $this->isWatchSupported();
+        $this->_watchedKeys = false;
         $this->_redisClient->unwatch();
         return $this;
     }
 
     public function discard() {
-        $this->_redisClient->discard();
-        $this->reset();
-        $this->_discarded = true;
+        if ($this->_initialized === true || $this->_checkAndSet) {
+            $this->_redisClient->discard();
+            $this->reset();
+            $this->_discarded = true;
+        }
         return $this;
     }
 
@@ -954,6 +959,7 @@ class MultiExecBlock {
                 );
             }
             if (count($this->_commands) > 0) {
+                $this->discard();
                 throw new ClientException(
                     'Cannot execute a transaction block after using fluent interface'
                 );
@@ -988,9 +994,7 @@ class MultiExecBlock {
                 }
                 catch (\Exception $exception) {
                     $blockException = $exception;
-                    if ($this->_initialized === true) {
-                        $this->discard();
-                    }
+                    $this->discard();
                 }
                 $this->_insideBlock = false;
                 if ($blockException !== null) {
@@ -998,7 +1002,11 @@ class MultiExecBlock {
                 }
             }
 
-            if ($this->_initialized === false || count($this->_commands) == 0) {
+            if (count($this->_commands) === 0) {
+                if ($this->_watchedKeys) {
+                    $this->_redisClient->discard();
+                    return;
+                }
                 return;
             }