Slides - PHP and MySql

advertisement
Transactions
Dr. Charles Severance
www.php-intro.com
Transactions
Transaction processing is designed to maintain a
database Integrity (typically a database or some modern
filesystems) in a known, consistent state, by ensuring
that interdependent operations on the system are either
all completed successfully or all canceled successfully.
http://en.wikipedia.org/wiki/Transaction_proces
sing
Transactions and MySQL
CREATE TABLE webauto_rps (
rps_guid VARCHAR(64) NOT NULL,
...
) ENGINE = InnoDB DEFAULT CHARSET=utf8;
Bank
Balance:
200
ATM
ATM
Bank
Balance:
200
ATM
ATM
Balance:
200
Bank
Balance:
200
ATM
ATM
Balance:
200
Balance:
200
Bank
Balance:
200
ATM
ATM
Balance:
200
Balance:
200
Bank
Balance:
100
ATM
ATM
Balance:
100
$100
Balance:
200
Bank
Balance:
100
ATM
ATM
Balance:
100
$100
Balance:
100
$100
Bank
Balance:
100
ATM
ATM
Balance:
100
$100
Balance:
100
$100
Awesom
e!
Transactions
•
•
•
Allows a sequence of steps to work as a unit or not work at all
Handles the fact that some things take time
Locks data on read so that it cannot be read by another
transaction unti the current transaction completes
Transactions in MySQL
•
•
•
•
•
Tables where transactions will be used require the use of the
InnoDB engine.
BEGIN - Starts a transaction
SELECT .... FOR UPDATE – Reads and locks row (or rows)
COMMIT - Completes a transaction
ROLLBACK - Gives up on a transaction
CREATE TABLE accounts (
number INT,
balance FLOAT,
PRIMARY KEY(number)
) ENGINE InnoDB;
INSERT INTO accounts(number, balance) VALUES(12345, 1025);
INSERT INTO accounts(number, balance) VALUES(67890, 140);
mysql> select * from accounts;
+--------+---------+
| number | balance |
+--------+---------+
| 12345 |
1025 |
| 67890 |
140 |
+--------+---------+
2 rows in set (0.02 sec)
mysql>
BEGIN;
SELECT balance FROM accounts WHERE number=12345 FOR UPDATE;
UPDATE accounts SET balance=balance+25 WHERE number=12345;
COMMIT;
mysql> select * from accounts;
+--------+---------+
| number | balance |
+--------+---------+
| 12345 |
1050 |
| 67890 |
140 |
+--------+---------+
2 rows in set (0.00 sec)
mysql>
mysql> BEGIN;
mysql> UPDATE accounts SET balance=balance-250 WHERE number=12345;
mysql> UPDATE accounts SET balance=balance+250 WHERE number=67890;
mysql> SELECT * FROM accounts;
+--------+---------+
| number | balance |
+--------+---------+
| 12345 |
800 |
| 67890 |
390 |
+--------+---------+
mysql> ROLLBACK;
Query OK, 0 rows affected (0.34 sec)
mysql> SELECT * FROM accounts;
+--------+---------+
| number | balance |
+--------+---------+
| 12345 |
1050 |
| 67890 |
140 |
+--------+---------+
Transaction started
but not committed.
SELECT waits
Transaction started
but not committed.
SELECT timeout
Transaction started
but not committed.
UPDATE waits
Transaction
committed.
UPDATE
completes instantly
Balances properly
reflect both
reductions
Transaction Deadlock
•
•
•
If process A Locks X, and process B locks Y, and then process
A waits for Y and process B waits for Y - they wait forever
This is called a "deadlock"
Deadlocks are avoided by making sure all transactions take
locks in the same order - this way one will "win" at the beginning
not the others will wait at the beginning of the sequence.
Start two
transactions and
lock two accounts
Attempt to lock and
account but need
to wait....
Attempt to lock and
already locked
account - deadlock
First transaction
aborted so second
select immediately
gets lock
tsugi/samples/rps/play.php
$stmt = $pdo->prepare("SELECT rps_guid, play1, play2, displayname FROM {$p}rps
LEFT JOIN {$p}user ON {$p}rps.user1_id = {$p}user.user_id
WHERE play2 IS NULL ORDER BY started_at ASC LIMIT 1 FOR UPDATE");
$stmt1 = $pdo->prepare("UPDATE {$p}rps SET user2_id = :U2ID, play2 = :PLAY
WHERE rps_guid = :GUID");
$pdo->beginTransaction();
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ( $row == FALSE ) {
$pdo->rollBack();
} else {
$stmt1->execute(array(":U2ID" => $_SESSION['id'], ":PLAY" => $play,
":GUID" => $row['rps_guid']));
$pdo->commit();
}
Transactions
•
•
•
Transactions are essential in situations where critical data is
read, updated, and written in a way that timing is critical
But transactions incur a cost because they lock areas of the
database and pause other operations waiting for the transaction
to finish
There is both a resource and performance cost if transactions
are used excessively
Download