Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\Core\Database;
|
Chris@0
|
4
|
Chris@0
|
5 /**
|
Chris@0
|
6 * A wrapper class for creating and managing database transactions.
|
Chris@0
|
7 *
|
Chris@0
|
8 * Not all databases or database configurations support transactions. For
|
Chris@0
|
9 * example, MySQL MyISAM tables do not. It is also easy to begin a transaction
|
Chris@0
|
10 * and then forget to commit it, which can lead to connection errors when
|
Chris@0
|
11 * another transaction is started.
|
Chris@0
|
12 *
|
Chris@0
|
13 * This class acts as a wrapper for transactions. To begin a transaction,
|
Chris@0
|
14 * simply instantiate it. When the object goes out of scope and is destroyed
|
Chris@0
|
15 * it will automatically commit. It also will check to see if the specified
|
Chris@0
|
16 * connection supports transactions. If not, it will simply skip any transaction
|
Chris@0
|
17 * commands, allowing user-space code to proceed normally. The only difference
|
Chris@0
|
18 * is that rollbacks won't actually do anything.
|
Chris@0
|
19 *
|
Chris@0
|
20 * In the vast majority of cases, you should not instantiate this class
|
Chris@0
|
21 * directly. Instead, call ->startTransaction(), from the appropriate connection
|
Chris@0
|
22 * object.
|
Chris@0
|
23 */
|
Chris@0
|
24 class Transaction {
|
Chris@0
|
25
|
Chris@0
|
26 /**
|
Chris@0
|
27 * The connection object for this transaction.
|
Chris@0
|
28 *
|
Chris@0
|
29 * @var \Drupal\Core\Database\Connection
|
Chris@0
|
30 */
|
Chris@0
|
31 protected $connection;
|
Chris@0
|
32
|
Chris@0
|
33 /**
|
Chris@0
|
34 * A boolean value to indicate whether this transaction has been rolled back.
|
Chris@0
|
35 *
|
Chris@0
|
36 * @var bool
|
Chris@0
|
37 */
|
Chris@0
|
38 protected $rolledBack = FALSE;
|
Chris@0
|
39
|
Chris@0
|
40 /**
|
Chris@0
|
41 * The name of the transaction.
|
Chris@0
|
42 *
|
Chris@0
|
43 * This is used to label the transaction savepoint. It will be overridden to
|
Chris@0
|
44 * 'drupal_transaction' if there is no transaction depth.
|
Chris@0
|
45 */
|
Chris@0
|
46 protected $name;
|
Chris@0
|
47
|
Chris@0
|
48 public function __construct(Connection $connection, $name = NULL) {
|
Chris@0
|
49 $this->connection = $connection;
|
Chris@0
|
50 // If there is no transaction depth, then no transaction has started. Name
|
Chris@0
|
51 // the transaction 'drupal_transaction'.
|
Chris@0
|
52 if (!$depth = $connection->transactionDepth()) {
|
Chris@0
|
53 $this->name = 'drupal_transaction';
|
Chris@0
|
54 }
|
Chris@0
|
55 // Within transactions, savepoints are used. Each savepoint requires a
|
Chris@0
|
56 // name. So if no name is present we need to create one.
|
Chris@0
|
57 elseif (!$name) {
|
Chris@0
|
58 $this->name = 'savepoint_' . $depth;
|
Chris@0
|
59 }
|
Chris@0
|
60 else {
|
Chris@0
|
61 $this->name = $name;
|
Chris@0
|
62 }
|
Chris@0
|
63 $this->connection->pushTransaction($this->name);
|
Chris@0
|
64 }
|
Chris@0
|
65
|
Chris@0
|
66 public function __destruct() {
|
Chris@0
|
67 // If we rolled back then the transaction would have already been popped.
|
Chris@0
|
68 if (!$this->rolledBack) {
|
Chris@0
|
69 $this->connection->popTransaction($this->name);
|
Chris@0
|
70 }
|
Chris@0
|
71 }
|
Chris@0
|
72
|
Chris@0
|
73 /**
|
Chris@0
|
74 * Retrieves the name of the transaction or savepoint.
|
Chris@0
|
75 */
|
Chris@0
|
76 public function name() {
|
Chris@0
|
77 return $this->name;
|
Chris@0
|
78 }
|
Chris@0
|
79
|
Chris@0
|
80 /**
|
Chris@0
|
81 * Rolls back the current transaction.
|
Chris@0
|
82 *
|
Chris@0
|
83 * This is just a wrapper method to rollback whatever transaction stack we are
|
Chris@0
|
84 * currently in, which is managed by the connection object itself. Note that
|
Chris@0
|
85 * logging (preferable with watchdog_exception()) needs to happen after a
|
Chris@0
|
86 * transaction has been rolled back or the log messages will be rolled back
|
Chris@0
|
87 * too.
|
Chris@0
|
88 *
|
Chris@0
|
89 * @see \Drupal\Core\Database\Connection::rollBack()
|
Chris@0
|
90 * @see watchdog_exception()
|
Chris@0
|
91 */
|
Chris@0
|
92 public function rollBack() {
|
Chris@0
|
93 $this->rolledBack = TRUE;
|
Chris@0
|
94 $this->connection->rollBack($this->name);
|
Chris@0
|
95 }
|
Chris@0
|
96
|
Chris@0
|
97 }
|