]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-14992 pg session locking (8.2 and later only), refactoring and db session not...
authorskodak <skodak>
Sat, 17 Jan 2009 14:31:29 +0000 (14:31 +0000)
committerskodak <skodak>
Sat, 17 Jan 2009 14:31:29 +0000 (14:31 +0000)
lib/dml/moodle_database.php
lib/dml/mysqli_native_moodle_database.php
lib/dml/pgsql_native_moodle_database.php
lib/sessionlib.php

index 1bd57b206ee319b0fb3bb82bf5e1d0fc956b8a7e..31c1fc0f2a0145391165d20a5801b1e7a8666890 100644 (file)
@@ -77,7 +77,7 @@ abstract class moodle_database {
     protected $last_type;
     protected $last_extrainfo;
 
-    protected $used_for_db_sessions = 0;
+    protected $used_for_db_sessions = false;
 
     /** internal temporary variable */
     private $fix_sql_params_i;
@@ -98,13 +98,6 @@ abstract class moodle_database {
         $this->dispose();
     }
 
-    /**
-     * Called only from session code!
-     */
-    public function used_for_db_sessions() {
-        $this->used_for_db_sessions = 1;
-    }
-
     /**
      * Detects if all needed PHP stuff installed.
      * Note: can be used before connect()
@@ -254,7 +247,7 @@ abstract class moodle_database {
         if ($this->used_for_db_sessions) {
             // this is needed because we need to save session to db before closing it
             session_write_close();
-            $this->used_for_db_sessions = 0;
+            $this->used_for_db_sessions = false;
         }
         if ($this->database_manager) {
             $this->database_manager->dispose();
@@ -1740,14 +1733,15 @@ abstract class moodle_database {
     }
 
 /// session locking
+    public function session_lock_supported() {
+        return false;
+    }
+
     public function get_session_lock($rowid) {
-        // TODO: make this abstract
-        return true;
+        $this->used_for_db_sessions = true;
     }
 
     public function release_session_lock($rowid) {
-        // TODO: make this abstract
-        return true;
     }
 
 /// performance and logging
index c5f7696f15978c5d55e9de8f1f2d013f57c9ced2..40682444930d926101b9cbdf9a9405c92fb2f51a 100644 (file)
@@ -881,7 +881,12 @@ class mysqli_native_moodle_database extends moodle_database {
     }
 
 /// session locking
+    public function session_lock_supported() {
+        return true;
+    }
+
     public function get_session_lock($rowid) {
+        parent::get_session_lock($rowid);
         $fullname = $this->dbname.'-'.$this->prefix.'-session-'.$rowid;
         $sql = "SELECT GET_LOCK('$fullname',120)";
         $this->query_start($sql, null, SQL_QUERY_AUX);
@@ -893,17 +898,16 @@ class mysqli_native_moodle_database extends moodle_database {
             $result->close();
 
             if (reset($arr) == 1) {
-                return true;
+                return;
             } else {
                 // try again!
-                return $this->get_session_lock($rowid);
+                $this->get_session_lock($rowid);
             }
         }
-
-        return false;
     }
 
     public function release_session_lock($rowid) {
+        parent::release_session_lock($rowid);
         $fullname = $this->dbname.'-'.$this->prefix.'-session-'.$rowid;
         $sql = "SELECT RELEASE_LOCK('$fullname')";
         $this->query_start($sql, null, SQL_QUERY_AUX);
@@ -911,15 +915,8 @@ class mysqli_native_moodle_database extends moodle_database {
         $this->query_end($result);
 
         if ($result) {
-            $arr = $result->fetch_assoc();
             $result->close();
-
-            if (reset($arr) == 1) {
-                return true;
-            }
         }
-
-        return false;
     }
 
 /// transactions
index 70884332fb00c935d2d167d2fc8341d5c5d1d4f3..a54797d113caa8b250440d9ecdb4967c53747871 100644 (file)
@@ -1047,6 +1047,46 @@ class pgsql_native_moodle_database extends moodle_database {
         return $positivematch ? '~*' : '!~*';
     }
 
+/// session locking
+    public function session_lock_supported() {
+        return $this->is_min_version('8.2.0');
+    }
+
+    public function get_session_lock($rowid) {
+        // TODO: there is a potential locking problem for database running
+        //       multiple instances of moodle, we could try to use pg_advisory_lock(int, int),
+        //       luckily there is not a big chance that they would collide
+        if (!$this->session_lock_supported()) {
+            return;
+        }
+
+        parent::get_session_lock($rowid);
+        $sql = "SELECT pg_advisory_lock($rowid)";
+        $this->query_start($sql, null, SQL_QUERY_AUX);
+        $result = pg_query($this->pgsql, $sql);
+        $this->query_end($result);
+
+        if ($result) {
+            pg_free_result($result);
+        }
+    }
+
+    public function release_session_lock($rowid) {
+        if (!$this->session_lock_supported()) {
+            return;
+        }
+        parent::release_session_lock($rowid);
+
+        $sql = "SELECT pg_advisory_unlock($rowid)";
+        $this->query_start($sql, null, SQL_QUERY_AUX);
+        $result = pg_query($this->pgsql, $sql);
+        $this->query_end($result);
+
+        if ($result) {
+            pg_free_result($result);
+        }
+    }
+
 /// transactions
     /**
      * on DBs that support it, switch to transaction mode and begin a transaction
index cf058bd1a81455adb14f97dff49bcc01a467c3b3..a4b4bf54a4167314e5ae915369db77120ac46153 100644 (file)
@@ -5,7 +5,7 @@
  * @return moodle_session
  */
 function session_get_instance() {
-    global $CFG;
+    global $CFG, $DB;
 
     static $session = null;
 
@@ -18,7 +18,8 @@ function session_get_instance() {
             $session_class = SESSION_CUSTOM;
             $session = new $session_class();
 
-        } else if (!isset($CFG->dbsessions) or $CFG->dbsessions) {
+        //} else if ((!isset($CFG->dbsessions) or $CFG->dbsessions) and $DB->session_lock_supported()) {
+        } else if (!empty($CFG->dbsessions) and $DB->session_lock_supported()) {
             // default recommended session type
             $session = new database_session();
 
@@ -299,8 +300,6 @@ class database_session extends session_stub {
         global $DB;
 
         $this->database = $DB;
-        $this->database->used_for_db_sessions();
-
         return true;
     }