Index: trunk/phase3/includes/ConcurrencyCheck.php |
— | — | @@ -212,7 +212,7 @@ |
213 | 213 | } |
214 | 214 | |
215 | 215 | public function status( $keys ) { |
216 | | - global $wgMemc; |
| 216 | + global $wgMemc, $wgDBtype; |
217 | 217 | $dbw = $this->dbw; |
218 | 218 | $now = time(); |
219 | 219 | |
— | — | @@ -243,8 +243,6 @@ |
244 | 244 | // If it's time to go to the database, go ahead and expire old rows. |
245 | 245 | $this->expire(); |
246 | 246 | |
247 | | - // the transaction seems incongruous, I know, but it's to keep the cache update atomic. |
248 | | - $dbw->begin(); |
249 | 247 | |
250 | 248 | // Why LOCK IN SHARE MODE, you might ask? To avoid a race condition: Otherwise, it's possible for |
251 | 249 | // a checkin and/or checkout to occur between this select and the value being stored in cache, which |
— | — | @@ -258,6 +256,14 @@ |
259 | 257 | // |
260 | 258 | // It appears all the DBMSes we use support LOCK IN SHARE MODE, but if that's not the case, the second |
261 | 259 | // solution above could be implemented instead. |
| 260 | + $queryParams = array(); |
| 261 | + if( $wgDBtype === 'mysql' ) { |
| 262 | + $queryParamsp[] = 'LOCK IN SHARE MODE'; |
| 263 | + |
| 264 | + // the transaction seems incongruous, I know, but it's to keep the cache update atomic. |
| 265 | + $dbw->begin(); |
| 266 | + } |
| 267 | + |
262 | 268 | $res = $dbw->select( |
263 | 269 | 'concurrencycheck', |
264 | 270 | array( '*' ), |
— | — | @@ -267,23 +273,29 @@ |
268 | 274 | 'cc_expiration > ' . $dbw->addQuotes( wfTimestamp( TS_MW ) ), |
269 | 275 | ), |
270 | 276 | __METHOD__, |
271 | | - array('LOCK IN SHARE MODE') |
| 277 | + $queryParams |
272 | 278 | ); |
273 | 279 | |
274 | 280 | while( $res && $record = $res->fetchRow() ) { |
275 | 281 | $record['status'] = 'valid'; |
276 | 282 | $checkouts[ $record['cc_record'] ] = $record; |
277 | 283 | |
278 | | - // safe to store values since this is inside the transaction |
279 | | - $wgMemc->set( |
280 | | - wfMemcKey( 'concurrencycheck', $this->resourceType, $record['cc_record'] ), |
281 | | - array( 'userId' => $record['cc_user'], 'expiration' => $record['cc_expiration'] ), |
282 | | - $record['cc_expiration'] - time() |
283 | | - ); |
| 284 | + // TODO: implement strategy #2 above, determine which DBMSes need which method. |
| 285 | + // for now, disable adding to cache here for databases that don't support read locking |
| 286 | + if( $wgDBtype !== 'mysql' ) { |
| 287 | + // safe to store values since this is inside the transaction |
| 288 | + $wgMemc->set( |
| 289 | + wfMemcKey( 'concurrencycheck', $this->resourceType, $record['cc_record'] ), |
| 290 | + array( 'userId' => $record['cc_user'], 'expiration' => $record['cc_expiration'] ), |
| 291 | + $record['cc_expiration'] - time() |
| 292 | + ); |
| 293 | + } |
284 | 294 | } |
285 | 295 | |
286 | | - // end the transaction. |
287 | | - $dbw->rollback(); |
| 296 | + if( $wgDBtype === 'mysql' ) { |
| 297 | + // end the transaction. |
| 298 | + $dbw->rollback(); |
| 299 | + } |
288 | 300 | } |
289 | 301 | |
290 | 302 | // if a key was passed in but has no (unexpired) checkout, include it in the |