Merge "Various database class cleanups"
[lhc/web/wiklou.git] / includes / objectcache / SqlBagOStuff.php
index 98b6eb9..84936a4 100644 (file)
@@ -91,6 +91,9 @@ class SqlBagOStuff extends BagOStuff {
         */
        public function __construct( $params ) {
                parent::__construct( $params );
+
+               $this->attrMap[self::ATTR_EMULATION] = self::QOS_EMULATION_SQL;
+
                if ( isset( $params['servers'] ) ) {
                        $this->serverInfos = [];
                        $this->serverTags = [];
@@ -468,6 +471,27 @@ class SqlBagOStuff extends BagOStuff {
                return $ok;
        }
 
+       public function changeTTL( $key, $expiry = 0 ) {
+               list( $serverIndex, $tableName ) = $this->getTableByKey( $key );
+               try {
+                       $db = $this->getDB( $serverIndex );
+                       $db->update(
+                               $tableName,
+                               [ 'exptime' => $db->timestamp( $this->convertExpiry( $expiry ) ) ],
+                               [ 'keyname' => $key, 'exptime > ' . $db->addQuotes( $db->timestamp( time() ) ) ],
+                               __METHOD__
+                       );
+                       if ( $db->affectedRows() == 0 ) {
+                               return false;
+                       }
+               } catch ( DBError $e ) {
+                       $this->handleWriteError( $e, $serverIndex );
+                       return false;
+               }
+
+               return true;
+       }
+
        /**
         * @param IDatabase $db
         * @param string $exptime
@@ -671,6 +695,7 @@ class SqlBagOStuff extends BagOStuff {
         *
         * @param DBError $exception
         * @param int $serverIndex
+        * @throws Exception
         */
        protected function handleWriteError( DBError $exception, $serverIndex ) {
                if ( $exception instanceof DBConnectionError ) {
@@ -678,6 +703,13 @@ class SqlBagOStuff extends BagOStuff {
                }
                if ( $exception->db && $exception->db->wasReadOnlyError() ) {
                        if ( $exception->db->trxLevel() ) {
+                               if ( !$this->serverInfos ) {
+                                       // Errors like deadlocks and connection drops already cause rollback.
+                                       // For consistency, we have no choice but to throw an error and trigger
+                                       // complete rollback if the main DB is also being used as the cache DB.
+                                       throw $exception;
+                               }
+
                                try {
                                        $exception->db->rollback( __METHOD__ );
                                } catch ( DBError $e ) {