Merge ".mailmap: Correct two contributor names"
[mediawiki.git] / includes / libs / rdbms / database / IDatabase.php
blob3882da6a5b8016d4b6a018dc57afeb1bb452cf67
1 <?php
2 /**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
18 * @file
20 namespace Wikimedia\Rdbms;
22 use Exception;
23 use Wikimedia\ScopedCallback;
25 /**
26 * @defgroup Database Database
27 * This group deals with database interface functions
28 * and query specifics/optimisations.
31 /**
32 * Interface to a relational database
34 * This is used for both primary databases and replicas, and used for both concrete
35 * connections, as well as wrappers around shared connections, like DBConnRef.
37 * As such, callers should not assume that the object represents a live connection
38 * (when using DBConnRef, the object may lazily defer the connection to the first query),
39 * and should not assume that they have complete control over the connection
40 * (when using DBConnRef, multiple objects may automatically share and reuse the same
41 * underlying connection).
43 * @ingroup Database
45 interface IDatabase extends IReadableDatabase {
46 /** Callback triggered immediately due to no active transaction */
47 public const TRIGGER_IDLE = 1;
48 /** Callback triggered by COMMIT */
49 public const TRIGGER_COMMIT = 2;
50 /** Callback triggered by ROLLBACK */
51 public const TRIGGER_ROLLBACK = 3;
52 /** Callback triggered by atomic section cancel (ROLLBACK TO SAVEPOINT) */
53 public const TRIGGER_CANCEL = 4;
55 /** Transaction is requested by regular caller outside of the DB layer */
56 public const TRANSACTION_EXPLICIT = '';
57 /** Transaction is requested internally via DBO_TRX/startAtomic() */
58 public const TRANSACTION_INTERNAL = 'implicit';
60 /** Atomic section is not cancelable */
61 public const ATOMIC_NOT_CANCELABLE = '';
62 /** Atomic section is cancelable */
63 public const ATOMIC_CANCELABLE = 'cancelable';
65 /** Commit/rollback is from outside the IDatabase handle and connection manager */
66 public const FLUSHING_ONE = '';
67 /**
68 * Commit/rollback is from the owning connection manager for the IDatabase handle
69 * @internal Only for use within the rdbms library
71 public const FLUSHING_ALL_PEERS = 'flush';
72 /**
73 * Commit/rollback is from the IDatabase handle internally
74 * @internal Only for use within the rdbms library
76 public const FLUSHING_INTERNAL = 'flush-internal';
78 /** Estimate total time (RTT, scanning, waiting on locks, applying) */
79 public const ESTIMATE_TOTAL = 'total';
80 /** Estimate time to apply (scanning, applying) */
81 public const ESTIMATE_DB_APPLY = 'apply';
83 /** Flag to return the lock acquisition timestamp (null if not acquired) */
84 public const LOCK_TIMESTAMP = 1;
86 /**
87 * Field for getLBInfo()/setLBInfo(); relevant transaction round level (1 or 0)
88 * @internal For use in the rdbms library only
90 public const LB_TRX_ROUND_LEVEL = 'trxRoundLevel';
91 /**
92 * Field for getLBInfo()/setLBInfo(); relevant transaction round owner name or null
93 * @internal For use in the rdbms library only
95 public const LB_TRX_ROUND_FNAME = 'trxRoundOwner';
96 /**
97 * Field for getLBInfo()/setLBInfo(); configured read-only mode explanation or false
98 * @internal For use in the rdbms library only
100 public const LB_READ_ONLY_REASON = 'readOnlyReason';
102 * Alias to LB_TRX_ROUND_FNAME
103 * @deprecated Since 1.44
105 public const LB_TRX_ROUND_ID = self::LB_TRX_ROUND_FNAME;
107 /** Primary server than can stream writes to replica servers */
108 public const ROLE_STREAMING_MASTER = 'streaming-master';
109 /** Replica server that receives writes from a primary server */
110 public const ROLE_STREAMING_REPLICA = 'streaming-replica';
111 /** Replica server within a static dataset */
112 public const ROLE_STATIC_CLONE = 'static-clone';
113 /** Server with unknown topology role */
114 public const ROLE_UNKNOWN = 'unknown';
117 * Gets the current transaction level.
119 * Historically, transactions were allowed to be "nested". This is no
120 * longer supported, so this function really only returns a boolean.
122 * @return int The previous value
124 public function trxLevel();
127 * Get the UNIX timestamp of the time that the transaction was established
129 * This can be used to reason about the staleness of SELECT data in REPEATABLE-READ
130 * transaction isolation level. Callers can assume that if a view-snapshot isolation
131 * is used, then the data read by SQL queries is *at least* up to date to that point
132 * (possibly more up-to-date since the first SELECT defines the snapshot).
134 * @return float|null Returns null if there is not active transaction
135 * @since 1.25
137 public function trxTimestamp();
140 * Check whether there is a transaction open at the specific request of a caller
142 * Explicit transactions are spawned by begin(), startAtomic(), and doAtomicSection().
143 * Note that explicit transactions should not be confused with explicit transaction rounds.
145 * @return bool
146 * @since 1.28
148 public function explicitTrxActive();
151 * Get properties passed down from the server info array of the load balancer
153 * @internal should not be called outside of rdbms library.
155 * @param string|null $name The entry of the info array to get, or null to get the whole array
156 * @return array|mixed|null
158 public function getLBInfo( $name = null );
161 * Get the sequence-based ID assigned by the last query method call
163 * This method should only be called when all the following hold true:
164 * - (a) A method call was made to insert(), upsert(), replace(), or insertSelect()
165 * - (b) The method call attempts to insert exactly one row
166 * - (c) The method call omits the value of exactly one auto-increment column
167 * - (d) The method call succeeded
168 * - (e) No subsequent method calls were made, with the exception of affectedRows(),
169 * lastErrno(), lastError(), and getType()
171 * In all other cases, the return value is unspecified.
173 * When the query method is either insert() with "IGNORE", upsert(), or insertSelect(),
174 * callers should first check affectedRows() before calling this method, making sure that
175 * the query method actually created a row. Otherwise, an ID from a previous insert might
176 * be incorrectly assumed to belong to last insert.
178 * @return int
180 public function insertId();
183 * Get the number of rows affected by the last query method call
185 * This method should only be called when all the following hold true:
186 * - (a) A method call was made to insert(), upsert(), replace(), update(), delete(),
187 * insertSelect(), query() with a non-SELECT statement, or queryMulti() with a
188 * non-SELECT terminal statement
189 * - (b) The method call succeeded
190 * - (c) No subsequent method calls were made, with the exception of affectedRows(),
191 * lastErrno(), lastError(), and getType()
193 * In all other cases, the return value is unspecified.
195 * UPDATE queries consider rows affected even when all their new column values match
196 * the previous values. Such rows can be excluded from the count by changing the WHERE
197 * clause to filter them out.
199 * If the last query method call was to query() or queryMulti(), then the results
200 * are based on the (last) statement provided to that call and are driver-specific.
202 * @return int
204 public function affectedRows();
207 * Run an SQL query statement and return the result
209 * If a connection loss is detected, then an attempt to reconnect will be made.
210 * For queries that involve no larger transactions or locks, they will be re-issued
211 * for convenience, provided the connection was re-established.
213 * In new code, the query wrappers select(), insert(), update(), delete(),
214 * etc. should be used where possible, since they give much better DBMS
215 * independence and automatically quote or validate user input in a variety
216 * of contexts. This function is generally only useful for queries which are
217 * explicitly DBMS-dependent and are unsupported by the query wrappers, such
218 * as CREATE TABLE.
220 * However, the query wrappers themselves should call this function.
222 * Callers should avoid the use of statements like BEGIN, COMMIT, and ROLLBACK.
223 * Methods like startAtomic(), endAtomic(), and cancelAtomic() can be used instead.
225 * @param string|Query $sql Single-statement SQL query
226 * @param-taint $sql exec_sql
227 * @param string $fname Caller name; used for profiling/SHOW PROCESSLIST comments @phan-mandatory-param
228 * @param int $flags Bit field of ISQLPlatform::QUERY_* constants
229 * @return bool|IResultWrapper True for a successful write query, IResultWrapper object
230 * for a successful read query, or false on failure if QUERY_SILENCE_ERRORS is set
231 * @return-taint tainted
232 * @throws DBQueryError If the query is issued, fails, and QUERY_SILENCE_ERRORS is not set
233 * @throws DBExpectedError If the query is not, and cannot, be issued yet (non-DBQueryError)
234 * @throws DBError If the query is inherently not allowed (non-DBExpectedError)
236 public function query( $sql, $fname = __METHOD__, $flags = 0 );
239 * Get an UpdateQueryBuilder bound to this connection. This is overridden by
240 * DBConnRef.
242 * @note A new query builder must be created per query. Query builders
243 * should not be reused since this uses a fluent interface and the state of
244 * the builder changes during the query which may cause unexpected results.
246 * @return UpdateQueryBuilder
248 public function newUpdateQueryBuilder(): UpdateQueryBuilder;
251 * Get an DeleteQueryBuilder bound to this connection. This is overridden by
252 * DBConnRef.
254 * @note A new query builder must be created per query. Query builders
255 * should not be reused since this uses a fluent interface and the state of
256 * the builder changes during the query which may cause unexpected results.
258 * @return DeleteQueryBuilder
260 public function newDeleteQueryBuilder(): DeleteQueryBuilder;
263 * Get an InsertQueryBuilder bound to this connection. This is overridden by
264 * DBConnRef.
266 * @note A new query builder must be created per query. Query builders
267 * should not be reused since this uses a fluent interface and the state of
268 * the builder changes during the query which may cause unexpected results.
270 * @return InsertQueryBuilder
272 public function newInsertQueryBuilder(): InsertQueryBuilder;
275 * Get an ReplaceQueryBuilder bound to this connection. This is overridden by
276 * DBConnRef.
278 * @note A new query builder must be created per query. Query builders
279 * should not be reused since this uses a fluent interface and the state of
280 * the builder changes during the query which may cause unexpected results.
282 * @return ReplaceQueryBuilder
284 public function newReplaceQueryBuilder(): ReplaceQueryBuilder;
287 * Lock all rows meeting the given conditions/options FOR UPDATE
289 * @param string|string[] $table The unqualified name of table(s) (use an array for a join)
290 * @phpcs:ignore Generic.Files.LineLength
291 * @param string|IExpression|array<string,?scalar|non-empty-array<int,?scalar>|RawSQLValue>|array<int,string|IExpression> $conds
292 * Condition in the format of IDatabase::select() conditions
293 * @param string $fname Function name for profiling @phan-mandatory-param
294 * @param array $options Options for select ("FOR UPDATE" is added automatically)
295 * @param array $join_conds Join conditions
296 * @return int Number of matching rows found (and locked)
297 * @throws DBError If an error occurs, {@see query}
298 * @since 1.32
299 * @deprecated since 1.43; Use SelectQueryBuilder::acquireRowLocks
301 public function lockForUpdate(
302 $table, $conds = '', $fname = __METHOD__, $options = [], $join_conds = []
306 * Insert row(s) into a table, in the provided order
308 * This operation will be seen by affectedRows()/insertId() as one query statement,
309 * regardless of how many statements are actually sent by the class implementation.
311 * @internal callers outside of rdbms library should use InsertQueryBuilder instead.
313 * @param string $table The unqualified name of a table
314 * @param array|array[] $rows Row(s) to insert, as either:
315 * - A string-keyed map of (column name => value) defining a new row. Values are
316 * treated as literals and quoted appropriately; null is interpreted as NULL.
317 * - An integer-keyed list of such string-keyed maps, defining a list of new rows.
318 * The keys in each map must be identical to each other and in the same order.
319 * The rows must not collide with each other.
320 * @param string $fname Calling function name (use __METHOD__) for logs/profiling @phan-mandatory-param
321 * @param string|array $options Combination map/list where each string-keyed entry maps
322 * a non-boolean option to the option parameters and each integer-keyed value is the
323 * name of a boolean option. Supported options are:
324 * - IGNORE: Boolean: skip insertion of rows that would cause unique key conflicts.
325 * IDatabase::affectedRows() can be used to determine how many rows were inserted.
326 * @return bool Return true if no exception was thrown (deprecated since 1.33)
327 * @throws DBError If an error occurs, {@see query}
329 public function insert( $table, $rows, $fname = __METHOD__, $options = [] );
332 * Update all rows in a table that match a given condition
334 * This operation will be seen by affectedRows()/insertId() as one query statement,
335 * regardless of how many statements are actually sent by the class implementation.
337 * @internal callers outside of rdbms library should use UpdateQueryBuilder instead.
339 * @param string $table The unqualified name of a table
340 * @param-taint $table exec_sql
341 * @param array<string,?scalar|RawSQLValue>|array<int,string> $set
342 * Combination map/list where each string-keyed entry maps a column
343 * to a literal assigned value and each integer-keyed value is a SQL expression in the
344 * format of a column assignment within UPDATE...SET. The (column => value) entries are
345 * convenient due to automatic value quoting and conversion of null to NULL. The SQL
346 * assignment format is useful for updates like "column = column + X". All assignments
347 * have no defined execution order, so they should not depend on each other. Do not
348 * modify AUTOINCREMENT or UUID columns in assignments.
349 * @param-taint $set exec_sql_numkey
350 * @phpcs:ignore Generic.Files.LineLength
351 * @param string|IExpression|array<string,?scalar|non-empty-array<int,?scalar>|RawSQLValue>|array<int,string|IExpression> $conds
352 * Condition in the format of IDatabase::select() conditions.
353 * In order to prevent possible performance or replication issues or damaging a data
354 * accidentally, an empty condition for 'update' queries isn't allowed.
355 * IDatabase::ALL_ROWS should be passed explicitly in order to update all rows.
356 * @param-taint $conds exec_sql_numkey
357 * @param string $fname Calling function name (use __METHOD__) for logs/profiling @phan-mandatory-param
358 * @param-taint $fname exec_sql
359 * @param string|array $options Combination map/list where each string-keyed entry maps
360 * a non-boolean option to the option parameters and each integer-keyed value is the
361 * name of a boolean option. Supported options are:
362 * - IGNORE: Boolean: skip update of rows that would cause unique key conflicts.
363 * IDatabase::affectedRows() includes all matching rows,
364 * that includes also rows not updated due to key conflict.
365 * @param-taint $options none
366 * @return bool Return true if no exception was thrown (deprecated since 1.33)
367 * @return-taint none
368 * @throws DBError If an error occurs, {@see query}
370 public function update( $table, $set, $conds, $fname = __METHOD__, $options = [] );
373 * Insert row(s) into a table, in the provided order, while deleting conflicting rows
375 * Conflicts are determined by the provided unique indexes. Note that it is possible
376 * for the provided rows to conflict even among themselves; it is preferable for the
377 * caller to de-duplicate such input beforehand.
379 * Note some important implications of the deletion semantics:
380 * - If the table has an AUTOINCREMENT column and $rows omit that column, then any
381 * conflicting existing rows will be replaced with newer having higher values for
382 * that column, even if nothing else changed.
383 * - There might be worse contention than upsert() due to the use of gap-locking.
384 * This does not apply to RDBMS types that use predicate locking nor those that
385 * just lock the whole table or databases anyway.
387 * This operation will be seen by affectedRows()/insertId() as one query statement,
388 * regardless of how many statements are actually sent by the class implementation.
390 * @internal callers outside of rdbms library should use ReplaceQueryBuilder instead.
392 * @param string $table The unqualified name of a table
393 * @param string|string[]|string[][] $uniqueKeys Column name or non-empty list of column
394 * name lists that define all applicable unique keys on the table. There must only be
395 * one such key. Each unique key on the table is "applicable" unless either:
396 * - It involves an AUTOINCREMENT column for which no values are assigned in $rows
397 * - It involves a UUID column for which newly generated UUIDs are assigned in $rows
398 * @param array|array[] $rows Row(s) to insert, in the form of either:
399 * - A string-keyed map of (column name => value) defining a new row. Values are
400 * treated as literals and quoted appropriately; null is interpreted as NULL.
401 * Columns belonging to a key in $uniqueKeys must be defined here and non-null.
402 * - An integer-keyed list of such string-keyed maps, defining a list of new rows.
403 * The keys in each map must be identical to each other and in the same order.
404 * The rows must not collide with each other.
405 * @param string $fname Calling function name (use __METHOD__) for logs/profiling @phan-mandatory-param
406 * @throws DBError If an error occurs, {@see query}
408 public function replace( $table, $uniqueKeys, $rows, $fname = __METHOD__ );
411 * Upsert row(s) into a table, in the provided order, while updating conflicting rows
413 * Conflicts are determined by the provided unique indexes. Note that it is possible
414 * for the provided rows to conflict even among themselves; it is preferable for the
415 * caller to de-duplicate such input beforehand.
417 * This operation will be seen by affectedRows()/insertId() as one query statement,
418 * regardless of how many statements are actually sent by the class implementation.
420 * @internal callers outside of rdbms library should use InsertQueryBuilder instead.
422 * @param string $table The unqualified name of a table
423 * @param array|array[] $rows Row(s) to insert, in the form of either:
424 * - A string-keyed map of (column name => value) defining a new row. Values are
425 * treated as literals and quoted appropriately; null is interpreted as NULL.
426 * Columns belonging to a key in $uniqueKeys must be defined here and non-null.
427 * - An integer-keyed list of such string-keyed maps, defining a list of new rows.
428 * The keys in each map must be identical to each other and in the same order.
429 * The rows must not collide with each other.
430 * @param string|string[]|string[][] $uniqueKeys Column name or non-empty list of column
431 * name lists that define all applicable unique keys on the table. There must only be
432 * one such key. Each unique key on the table is "applicable" unless either:
433 * - It involves an AUTOINCREMENT column for which no values are assigned in $rows
434 * - It involves a UUID column for which newly generated UUIDs are assigned in $rows
435 * @param array<string,?scalar|RawSQLValue>|array<int,string> $set
436 * Combination map/list where each string-keyed entry maps a column
437 * to a literal assigned value and each integer-keyed value is a SQL assignment expression
438 * of the form "<unquoted alphanumeric column> = <SQL expression>". The (column => value)
439 * entries are convenient due to automatic value quoting and conversion of null to NULL.
440 * The SQL assignment entries are useful for updates like "column = column + X". All of
441 * the assignments have no defined execution order, so callers should make sure that they
442 * not depend on each other. Do not modify AUTOINCREMENT or UUID columns in assignments,
443 * even if they are just "secondary" unique keys. For multi-row upserts, use
444 * buildExcludedValue() to reference the value of a column from the corresponding row
445 * in $rows that conflicts with the current row.
446 * @param string $fname Calling function name (use __METHOD__) for logs/profiling @phan-mandatory-param
447 * @throws DBError If an error occurs, {@see query}
448 * @since 1.22
450 public function upsert(
451 $table, array $rows, $uniqueKeys, array $set, $fname = __METHOD__
455 * Delete all rows in a table that match a condition which includes a join
457 * For safety, an empty $conds will not delete everything. If you want to
458 * delete all rows where the join condition matches, set $conds=IDatabase::ALL_ROWS.
460 * DO NOT put the join condition in $conds.
462 * This operation will be seen by affectedRows()/insertId() as one query statement,
463 * regardless of how many statements are actually sent by the class implementation.
465 * @param string $delTable The unqualified name of the table to delete rows from.
466 * @param string $joinTable The unqualified name of the reference table to join on.
467 * @param string $delVar The variable to join on, in the first table.
468 * @param string $joinVar The variable to join on, in the second table.
469 * @phpcs:ignore Generic.Files.LineLength
470 * @param string|IExpression|array<string,?scalar|non-empty-array<int,?scalar>|RawSQLValue>|array<int,string|IExpression> $conds
471 * Condition array of field names mapped to variables,
472 * ANDed together in the WHERE clause
473 * @param string $fname Calling function name (use __METHOD__) for logs/profiling @phan-mandatory-param
474 * @throws DBError If an error occurs, {@see query}
476 public function deleteJoin(
477 $delTable,
478 $joinTable,
479 $delVar,
480 $joinVar,
481 $conds,
482 $fname = __METHOD__
486 * Delete all rows in a table that match a condition
488 * This operation will be seen by affectedRows()/insertId() as one query statement,
489 * regardless of how many statements are actually sent by the class implementation.
491 * @internal callers outside of rdbms library should use DeleteQueryBuilder instead.
493 * @param string $table The unqualified name of a table
494 * @param-taint $table exec_sql
495 * @phpcs:ignore Generic.Files.LineLength
496 * @param string|IExpression|array<string,?scalar|non-empty-array<int,?scalar>|RawSQLValue>|array<int,string|IExpression> $conds
497 * Array of conditions. See $conds in IDatabase::select()
498 * In order to prevent possible performance or replication issues or damaging a data
499 * accidentally, an empty condition for 'delete' queries isn't allowed.
500 * IDatabase::ALL_ROWS should be passed explicitly in order to delete all rows.
501 * @param-taint $conds exec_sql_numkey
502 * @param string $fname Name of the calling function @phan-mandatory-param
503 * @param-taint $fname exec_sql
504 * @return bool Return true if no exception was thrown (deprecated since 1.33)
505 * @return-taint none
506 * @throws DBError If an error occurs, {@see query}
508 public function delete( $table, $conds, $fname = __METHOD__ );
511 * INSERT SELECT wrapper
513 * @warning If the insert will use an auto-increment or sequence to
514 * determine the value of a column, this may break replication on
515 * databases using statement-based replication if the SELECT is not
516 * deterministically ordered.
518 * This operation will be seen by affectedRows()/insertId() as one query statement,
519 * regardless of how many statements are actually sent by the class implementation.
521 * @param string $destTable Unqualified name of destination table
522 * @param string|array $srcTable Unqualified name of source table(s) (use an array for a join)
523 * @param array $varMap Must be an associative array of the form
524 * [ 'dest1' => 'source1', ... ]. Source items may be literals
525 * rather than field names, but strings should be quoted with
526 * IDatabase::addQuotes()
527 * @phpcs:ignore Generic.Files.LineLength
528 * @param string|IExpression|array<string,?scalar|non-empty-array<int,?scalar>|RawSQLValue>|array<int,string|IExpression> $conds
529 * Condition array. See $conds in IDatabase::select() for
530 * the details of the format of condition arrays. May be "*" to copy the
531 * whole table.
532 * @param string $fname The function name of the caller, from __METHOD__ @phan-mandatory-param
533 * @param array $insertOptions Options for the INSERT part of the query, see
534 * IDatabase::insert() for details. Also, one additional option is
535 * available: pass 'NO_AUTO_COLUMNS' to hint that the query does not use
536 * an auto-increment or sequence to determine any column values.
537 * @param array $selectOptions Options for the SELECT part of the query, see
538 * IDatabase::select() for details.
539 * @param array $selectJoinConds Join conditions for the SELECT part of the query, see
540 * IDatabase::select() for details.
541 * @return bool Return true if no exception was thrown (deprecated since 1.33)
542 * @throws DBError If an error occurs, {@see query}
544 public function insertSelect(
545 $destTable,
546 $srcTable,
547 $varMap,
548 $conds,
549 $fname = __METHOD__,
550 $insertOptions = [],
551 $selectOptions = [],
552 $selectJoinConds = []
556 * Run a callback when the current transaction commits or rolls back
558 * An error is thrown if no transaction is pending.
560 * When transaction round mode (DBO_TRX) is set, the callback will run at the end
561 * of the round, just after all peer transactions COMMIT/ROLLBACK.
563 * This IDatabase instance will start off in auto-commit mode when the callback starts.
564 * The use of other IDatabase handles from the callback should be avoided unless they are
565 * known to be in auto-commit mode. Callbacks that create transactions via begin() or
566 * startAtomic() must have matching calls to commit()/endAtomic().
568 * Use this method only for the following purposes:
569 * - (a) Release of cooperative locks on resources
570 * - (b) Cancellation of in-process deferred tasks
572 * The callback takes the following arguments:
573 * - How the current atomic section (if any) or overall transaction (otherwise) ended
574 * (IDatabase::TRIGGER_COMMIT or IDatabase::TRIGGER_ROLLBACK)
575 * - This IDatabase instance (since 1.32)
577 * Callbacks will execute in the order they were enqueued.
579 * @param callable $callback
580 * @param string $fname Caller name @phan-mandatory-param
581 * @throws DBError If an error occurs, {@see query}
582 * @throws Exception If the callback runs immediately and an error occurs in it
583 * @since 1.28
585 public function onTransactionResolution( callable $callback, $fname = __METHOD__ );
588 * Run a callback when the current transaction commits or now if there is none
590 * If there is a transaction and it is rolled back, then the callback is cancelled.
592 * When transaction round mode (DBO_TRX) is set, the callback will run at the end
593 * of the round, just after all peer transactions COMMIT. If the transaction round
594 * is rolled back, then the callback is cancelled.
596 * This IDatabase instance will start off in auto-commit mode when the callback starts.
597 * The use of other IDatabase handles from the callback should be avoided unless they are
598 * known to be in auto-commit mode. Callbacks that create transactions via begin() or
599 * startAtomic() must have matching calls to commit()/endAtomic().
601 * Use this method only for the following purposes:
602 * - (a) RDBMS updates, prone to lock timeouts/deadlocks, that do not require
603 * atomicity with respect to the updates in the current transaction (if any)
604 * - (b) Purges to lightweight cache services due to RDBMS updates
605 * - (c) Updates to secondary DBs/stores that must only commit once the updates in
606 * the current transaction (if any) are committed (e.g. insert user account row
607 * to DB1, then, initialize corresponding LDAP account)
609 * The callback takes the following arguments:
610 * - How the transaction ended (IDatabase::TRIGGER_COMMIT or IDatabase::TRIGGER_IDLE)
611 * - This IDatabase instance (since 1.32)
613 * Callbacks will execute in the order they were enqueued.
615 * @param callable $callback
616 * @param string $fname Caller name @phan-mandatory-param
617 * @throws DBError If an error occurs, {@see query}
618 * @throws Exception If the callback runs immediately and an error occurs in it
619 * @since 1.32
621 public function onTransactionCommitOrIdle( callable $callback, $fname = __METHOD__ );
624 * Run a callback before the current transaction commits or now if there is none
626 * If there is a transaction and it is rolled back, then the callback is cancelled.
628 * When transaction round mode (DBO_TRX) is set, the callback will run at the end
629 * of the round, just after all peer transactions COMMIT. If the transaction round
630 * is rolled back, then the callback is cancelled.
632 * If there is no current transaction, one will be created to wrap the callback.
633 * Callbacks cannot use begin()/commit() to manage transactions. The use of other
634 * IDatabase handles from the callback should be avoided.
636 * Use this method only for the following purposes:
637 * - a) RDBMS updates, prone to lock timeouts/deadlocks, that require atomicity
638 * with respect to the updates in the current transaction (if any)
639 * - b) Purges to lightweight cache services due to RDBMS updates
641 * The callback takes the one argument:
642 * - This IDatabase instance (since 1.32)
644 * Callbacks will execute in the order they were enqueued.
646 * @param callable $callback
647 * @param string $fname Caller name @phan-mandatory-param
648 * @throws DBError If an error occurs, {@see query}
649 * @throws Exception If the callback runs immediately and an error occurs in it
650 * @since 1.22
652 public function onTransactionPreCommitOrIdle( callable $callback, $fname = __METHOD__ );
655 * Begin an atomic section of SQL statements
657 * Start an implicit transaction if no transaction is already active, set a savepoint
658 * (if $cancelable is ATOMIC_CANCELABLE), and track the given section name to enforce
659 * that the transaction is not committed prematurely. The end of the section must be
660 * signified exactly once, either by endAtomic() or cancelAtomic(). Sections can have
661 * have layers of inner sections (sub-sections), but all sections must be ended in order
662 * of innermost to outermost. Transactions cannot be started or committed until all
663 * atomic sections are closed.
665 * ATOMIC_CANCELABLE is useful when the caller needs to handle specific failure cases
666 * by discarding the section's writes. This should not be used for failures when:
667 * - upsert() could easily be used instead
668 * - insert() with IGNORE could easily be used instead
669 * - select() with FOR UPDATE could be checked before issuing writes instead
670 * - The failure is from code that runs after the first write but doesn't need to
671 * - The failures are from contention solvable via onTransactionPreCommitOrIdle()
672 * - The failures are deadlocks; the RDBMs usually discard the whole transaction
674 * @note callers must use additional measures for situations involving two or more
675 * (peer) transactions (e.g. updating two database servers at once). The transaction
676 * and savepoint logic of this method only applies to this specific IDatabase instance.
678 * Example usage:
679 * @code
680 * // Start a transaction if there isn't one already
681 * $dbw->startAtomic( __METHOD__ );
682 * // Serialize these thread table updates
683 * $dbw->select( 'thread', '1', [ 'td_id' => $tid ], __METHOD__, 'FOR UPDATE' );
684 * // Add a new comment for the thread
685 * $dbw->insert( 'comment', $row, __METHOD__ );
686 * $cid = $db->insertId();
687 * // Update thread reference to last comment
688 * $dbw->update( 'thread', [ 'td_latest' => $cid ], [ 'td_id' => $tid ], __METHOD__ );
689 * // Demark the end of this conceptual unit of updates
690 * $dbw->endAtomic( __METHOD__ );
691 * @endcode
693 * Example usage (atomic changes that might have to be discarded):
694 * @code
695 * // Start a transaction if there isn't one already
696 * $sectionId = $dbw->startAtomic( __METHOD__, $dbw::ATOMIC_CANCELABLE );
697 * // Create new record metadata row
698 * $dbw->insert( 'records', $row, __METHOD__ );
699 * // Figure out where to store the data based on the new row's ID
700 * $path = $recordDirectory . '/' . $dbw->insertId();
701 * // Write the record data to the storage system
702 * $status = $fileBackend->create( [ 'dst' => $path, 'content' => $data ] );
703 * if ( $status->isOK() ) {
704 * // Try to cleanup files orphaned by transaction rollback
705 * $dbw->onTransactionResolution(
706 * function ( $type ) use ( $fileBackend, $path ) {
707 * if ( $type === IDatabase::TRIGGER_ROLLBACK ) {
708 * $fileBackend->delete( [ 'src' => $path ] );
710 * },
711 * __METHOD__
712 * );
713 * // Demark the end of this conceptual unit of updates
714 * $dbw->endAtomic( __METHOD__ );
715 * } else {
716 * // Discard these writes from the transaction (preserving prior writes)
717 * $dbw->cancelAtomic( __METHOD__, $sectionId );
719 * @endcode
721 * @since 1.23
722 * @param string $fname @phan-mandatory-param
723 * @param string $cancelable Pass self::ATOMIC_CANCELABLE to use a
724 * savepoint and enable self::cancelAtomic() for this section.
725 * @return AtomicSectionIdentifier section ID token
726 * @throws DBError If an error occurs, {@see query}
728 public function startAtomic( $fname = __METHOD__, $cancelable = self::ATOMIC_NOT_CANCELABLE );
731 * Ends an atomic section of SQL statements
733 * Ends the next section of atomic SQL statements and commits the transaction
734 * if necessary.
736 * @since 1.23
737 * @see IDatabase::startAtomic
738 * @param string $fname @phan-mandatory-param
739 * @throws DBError If an error occurs, {@see query}
741 public function endAtomic( $fname = __METHOD__ );
744 * Cancel an atomic section of SQL statements
746 * This will roll back only the statements executed since the start of the
747 * most recent atomic section, and close that section. If a transaction was
748 * open before the corresponding startAtomic() call, any statements before
749 * that call are *not* rolled back and the transaction remains open. If the
750 * corresponding startAtomic() implicitly started a transaction, that
751 * transaction is rolled back.
753 * @note callers must use additional measures for situations involving two or more
754 * (peer) transactions (e.g. updating two database servers at once). The transaction
755 * and savepoint logic of startAtomic() are bound to specific IDatabase instances.
757 * Note that a call to IDatabase::rollback() will also roll back any open atomic sections.
759 * @note As an optimization to save rountrips, this method may only be called
760 * when startAtomic() was called with the ATOMIC_CANCELABLE flag.
761 * @since 1.31
762 * @see IDatabase::startAtomic
763 * @param string $fname @phan-mandatory-param
764 * @param AtomicSectionIdentifier|null $sectionId Section ID from startAtomic();
765 * passing this enables cancellation of unclosed nested sections [optional]
766 * @throws DBError If an error occurs, {@see query}
768 public function cancelAtomic( $fname = __METHOD__, ?AtomicSectionIdentifier $sectionId = null );
771 * Perform an atomic section of reversible SQL statements from a callback
773 * The $callback takes the following arguments:
774 * - This database object
775 * - The value of $fname
777 * This will execute the callback inside a pair of startAtomic()/endAtomic() calls.
778 * If any exception occurs during execution of the callback, it will be handled as follows:
779 * - If $cancelable is ATOMIC_CANCELABLE, cancelAtomic() will be called to back out any
780 * (and only) statements executed during the atomic section. If that succeeds, then the
781 * exception will be re-thrown; if it fails, then a different exception will be thrown
782 * and any further query attempts will fail until rollback() is called.
783 * - If $cancelable is ATOMIC_NOT_CANCELABLE, cancelAtomic() will be called to mark the
784 * end of the section and the error will be re-thrown. Any further query attempts will
785 * fail until rollback() is called.
787 * This method is convenient for letting calls to the caller of this method be wrapped
788 * in a try/catch blocks for exception types that imply that the caller failed but was
789 * able to properly discard the changes it made in the transaction. This method can be
790 * an alternative to explicit calls to startAtomic()/endAtomic()/cancelAtomic().
792 * Example usage, "RecordStore::save" method:
793 * @code
794 * $dbw->doAtomicSection( __METHOD__, function ( $dbw ) use ( $record ) {
795 * // Create new record metadata row
796 * $dbw->insert( 'records', $record->toArray(), __METHOD__ );
797 * // Figure out where to store the data based on the new row's ID
798 * $path = $this->recordDirectory . '/' . $dbw->insertId();
799 * // Write the record data to the storage system;
800 * // blob store throws StoreFailureException on failure
801 * $this->blobStore->create( $path, $record->getJSON() );
802 * // Try to cleanup files orphaned by transaction rollback
803 * $dbw->onTransactionResolution(
804 * function ( $type ) use ( $path ) {
805 * if ( $type === IDatabase::TRIGGER_ROLLBACK ) {
806 * $this->blobStore->delete( $path );
808 * },
809 * __METHOD__
810 * );
811 * }, $dbw::ATOMIC_CANCELABLE );
812 * @endcode
814 * Example usage, caller of the "RecordStore::save" method:
815 * @code
816 * $dbw->startAtomic( __METHOD__ );
817 * // ...various SQL writes happen...
818 * try {
819 * $recordStore->save( $record );
820 * } catch ( StoreFailureException $e ) {
821 * // ...various SQL writes happen...
823 * // ...various SQL writes happen...
824 * $dbw->endAtomic( __METHOD__ );
825 * @endcode
827 * @see Database::startAtomic
828 * @see Database::endAtomic
829 * @see Database::cancelAtomic
831 * @param string $fname Caller name (usually __METHOD__) @phan-mandatory-param
832 * @param callable $callback Callback that issues write queries
833 * @param string $cancelable Pass self::ATOMIC_CANCELABLE to use a
834 * savepoint and enable self::cancelAtomic() for this section.
835 * @return mixed Result of the callback (since 1.28)
836 * @throws DBError If an error occurs, {@see query}
837 * @throws Exception If an error occurs in the callback
838 * @since 1.27; prior to 1.31 this did a rollback() instead of
839 * cancelAtomic(), and assumed no callers up the stack would ever try to
840 * catch the exception.
842 public function doAtomicSection(
843 $fname, callable $callback, $cancelable = self::ATOMIC_NOT_CANCELABLE
847 * Begin a transaction
849 * Only call this from code with outer transaction scope.
850 * See https://www.mediawiki.org/wiki/Database_transactions for details.
851 * Nesting of transactions is not supported.
853 * Note that when the DBO_TRX flag is set (which is usually the case for web
854 * requests, but not for maintenance scripts), any previous database query
855 * will have started a transaction automatically.
857 * Nesting of transactions is not supported. Attempts to nest transactions
858 * will cause a warning, unless the current transaction was started
859 * automatically because of the DBO_TRX flag.
861 * @param string $fname Calling function name @phan-mandatory-param
862 * @param string $mode A situationally valid IDatabase::TRANSACTION_* constant [optional]
863 * @throws DBError If an error occurs, {@see query}
865 public function begin( $fname = __METHOD__, $mode = self::TRANSACTION_EXPLICIT );
868 * Commits a transaction previously started using begin()
870 * If no transaction is in progress, a warning is issued.
872 * Only call this from code with outer transaction scope.
873 * See https://www.mediawiki.org/wiki/Database_transactions for details.
874 * Nesting of transactions is not supported.
876 * @param string $fname @phan-mandatory-param
877 * @param string $flush Flush flag, set to situationally valid IDatabase::FLUSHING_*
878 * constant to disable warnings about explicitly committing implicit transactions,
879 * or calling commit when no transaction is in progress.
880 * This will trigger an exception if there is an ongoing explicit transaction.
881 * Only set the flush flag if you are sure that these warnings are not applicable,
882 * and no explicit transactions are open.
883 * @throws DBError If an error occurs, {@see query}
885 public function commit( $fname = __METHOD__, $flush = self::FLUSHING_ONE );
888 * Rollback a transaction previously started using begin()
890 * Only call this from code with outer transaction scope.
891 * See https://www.mediawiki.org/wiki/Database_transactions for details.
892 * Nesting of transactions is not supported. If a serious unexpected error occurs,
893 * throwing an Exception is preferable, using a pre-installed error handler to trigger
894 * rollback (in any case, failure to issue COMMIT will cause rollback server-side).
896 * Query, connection, and onTransaction* callback errors will be suppressed and logged.
898 * @param string $fname Calling function name @phan-mandatory-param
899 * @param string $flush Flush flag, set to a situationally valid IDatabase::FLUSHING_*
900 * constant to disable warnings about explicitly rolling back implicit transactions.
901 * This will silently break any ongoing explicit transaction. Only set the flush flag
902 * if you are sure that it is safe to ignore these warnings in your context.
903 * @throws DBError If an error occurs, {@see query}
904 * @since 1.23 Added $flush parameter
906 public function rollback( $fname = __METHOD__, $flush = self::FLUSHING_ONE );
909 * Commit any transaction but error out if writes or callbacks are pending
911 * This is intended for clearing out REPEATABLE-READ snapshots so that callers can
912 * see a new point-in-time of the database. This is useful when one of many transaction
913 * rounds finished and significant time will pass in the script's lifetime. It is also
914 * useful to call on a replica server after waiting on replication to catch up to the
915 * primary server.
917 * @param string $fname Calling function name @phan-mandatory-param
918 * @param string $flush Flush flag, set to situationally valid IDatabase::FLUSHING_*
919 * constant to disable warnings about explicitly committing implicit transactions,
920 * or calling commit when no transaction is in progress.
921 * This will trigger an exception if there is an ongoing explicit transaction.
922 * Only set the flush flag if you are sure that these warnings are not applicable,
923 * and no explicit transactions are open.
924 * @throws DBError If an error occurs, {@see query}
925 * @since 1.28
926 * @since 1.34 Added $flush parameter
928 public function flushSnapshot( $fname = __METHOD__, $flush = self::FLUSHING_ONE );
931 * Override database's default behavior.
932 * Not all options are supported on all database backends;
933 * unsupported options are silently ignored.
935 * $options include:
936 * - 'connTimeout': Set the connection timeout value in seconds.
937 * May be useful for very long batch queries such as full-wiki dumps,
938 * where a single query reads out over hours or days.
939 * Only supported on MySQL and MariaDB.
940 * - 'groupConcatMaxLen': Maximum length of a GROUP_CONCAT() result.
941 * Only supported on MySQL and MariaDB.
943 * @param array $options
944 * @return void
945 * @throws DBError If an error occurs, {@see query}
947 public function setSessionOptions( array $options );
950 * Check to see if a named lock is not locked by any thread (non-blocking)
952 * @param string $lockName Name of lock to poll
953 * @param string $method Name of method calling us
954 * @return bool
955 * @throws DBError If an error occurs, {@see query}
956 * @since 1.20
958 public function lockIsFree( $lockName, $method );
961 * Acquire a named lock
963 * Named locks are not related to transactions
965 * @param string $lockName Name of lock to acquire
966 * @param string $method Name of the calling method
967 * @param int $timeout Acquisition timeout in seconds (0 means non-blocking)
968 * @param int $flags Bit field of IDatabase::LOCK_* constants
969 * @return bool|float|null Success (bool); acquisition time (float/null) if LOCK_TIMESTAMP
970 * @throws DBError If an error occurs, {@see query}
972 public function lock( $lockName, $method, $timeout = 5, $flags = 0 );
975 * Release a lock
977 * Named locks are not related to transactions
979 * @param string $lockName Name of lock to release
980 * @param string $method Name of the calling method
981 * @return bool Success
982 * @throws DBError If an error occurs, {@see query}
984 public function unlock( $lockName, $method );
987 * Acquire a named lock, flush any transaction, and return an RAII style unlocker object
989 * Only call this from outer transaction scope and when only one DB server will be affected.
990 * See https://www.mediawiki.org/wiki/Database_transactions for details.
992 * This is suitable for transactions that need to be serialized using cooperative locks,
993 * where each transaction can see each others' changes. Any transaction is flushed to clear
994 * out stale REPEATABLE-READ snapshot data. Once the returned object falls out of PHP scope,
995 * the lock will be released unless a transaction is active. If one is active, then the lock
996 * will be released when it either commits or rolls back.
998 * If the lock acquisition failed, then no transaction flush happens, and null is returned.
1000 * @param string $lockKey Name of lock to release
1001 * @param string $fname Name of the calling method
1002 * @param int $timeout Acquisition timeout in seconds
1003 * @return ScopedCallback|null
1004 * @throws DBError If an error occurs, {@see query}
1005 * @since 1.27
1007 public function getScopedLockAndFlush( $lockKey, $fname, $timeout );
1010 * Check if this DB server is marked as read-only according to load balancer info
1012 * @note LoadBalancer checks serverIsReadOnly() when setting the load balancer info array
1014 * @return bool
1015 * @since 1.27
1017 public function isReadOnly();