The focus of this article is to summarize MYSQL transactions.
What is a transaction
A transaction is simply a set of SQL executions that either all succeed or all fail. MYSQL transactions are implemented at the storage engine layer.
Transactions have ACID properties:
- Atomicity: A transaction must be treated as an indivisible unit;
- Consistency: the database always switches from one state to another;
- Isolation: Normally, transactions are not visible to other transactions until committed;
- Durablity: once a transaction is committed, the changes are persisted in the database permanently;
The most common example of a transaction is a bank transfer. Assume that Polo needs to transfer 1000 yuan to Lynn, as follows:
- Confirm that the polo account balance is more than 1000 yuan;
- Subtract 1000 yuan from polo’s account balance;
- Increase the balance of Lynn’s account by 1000 yuan;
The SQL statement is as follows:
mysql> BEGIN;
mysql> SELECT balance FROM bank_account WHERE uid=10001;
mysql> UPDATE bank_account SET balance=balance-1000 WHERE uid=10001;
mysql> UPDATE bank_account SET balance=balance+1000 WHERE uid=10002;
mysql> COMMIT;
Copy the code
Mysql can START a TRANSACTION with BEGIN or START TRANSACTION. The above three steps guarantee data integrity in a single transaction, and all of them either succeed or fail.
MYSQL provides two transactional engines: Innodb and NDBCluster. By default, automatic COMMIT mode is used. A statement is executed to automatically COMMIT. The AUTOCOMMIT variable enables or disables automatic commit mode:
mysql> SHOW VARIABLES LIKE "AUTOCOMMIT"; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | autocommit | ON | + -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + -- -- -- -- -- -- -- + 1 row in the set (0.00 SEC) mysql > set the AUTOCOMMIT mode = 1Copy the code
AUTOCOMMIT=1 indicates that default commit is enabled. 0 indicates that default commit is disabled and manual commit is required.
Isolation level
Explanation of transaction isolation: Typically, transactions are not visible to other transactions until they are committed.
There are four isolation levels for databases, and of course MYSQL is the same. Respectively is:
- READ UNCOMMITTED
- READ COMMITTED
- REPEATABLE READ
- Serialization, SEAIALIZABLE
Two understandings about isolation levels
- As the book explains, each level specifies which changes are made within a transaction and which are visible within and between transactions.
- As I understand it, the isolation level determines when changes made to one transaction are visible to another.
The difference is whether there is intra-transaction visibility, but the operations within a transaction are visible at any level, with the emphasis on inter-transaction visibility.
MYSQL > create isolation levels for MYSQL > create isolation levels for MYSQL > create isolation levels
mysql> CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8 |
Copy the code
There are only ID (primary key increment) and name fields
Uncommitted read
Changes in a transaction that are not committed are also visible to other transactions, commonly known as dirty reads. Very not recommended.
The example demonstrates that clients A and B set the isolation level to uncommitted reads
mysql> SET SESSION TX_ISOLATION='READ-UNCOMMITTED';
Copy the code
Clients A and B start the transaction and query student
Mysql > BEGIN; mysql> SELECT * FROM student; The Empty set (0.00 SEC)Copy the code
Currently, both clients A and B have empty data. Insert a new piece of data at customer side B
mysql> INSERT INTO student(name) VALUES("polo");
Query OK, 1 row affected (0.00 sec)
Copy the code
The transaction has not yet been committed, so client A checks the student table as follows:
mysql> SELECT * FROM student; + - + -- -- -- -- -- -- + | | id name | + - + -- -- -- -- -- -- + | | 1 polo | + + -- -- -- -- -- -- - + 1 row in the set (0.00 SEC)Copy the code
As you can see, client A sees B’s uncommitted changes. Client B performs the rollback as follows:
mysql> ROLLBACK
Copy the code
After success, client A looks at the student table:
mysql> SELECT * FROM student; The Empty set (0.00 SEC)Copy the code
The output shows that client A’s view data is empty.
The above illustrates the dangers of uncommitted read isolation levels. Changes made to one uncommitted transaction are visible to another transaction and can easily lead to dirty reads. Do not use this level except in special circumstances
Has been submitted to read
Most database systems default to this level (MYSQL does not). Committed read level means that a transaction can only see the changes made by committed transactions, which solves the problem of uncommitted reads, that is, dirty reads.
To demonstrate that clients A and B set the isolation level to committed read, run the following command:
mysql> SET SESSION TX_ISOLATION='READ-COMMITTED';
Copy the code
Clients A and B start the transaction and query student
mysql> BEGIN; mysql> SELECT * FROM student; The Empty set (0.00 SEC)Copy the code
The result shows that both clients A and B are empty. Next, client B inserts a new piece of data but does not commit:
mysql> INSERT INTO student (name) VALUES('polo');
Copy the code
Next, client A looks at the student data:
mysql> SELECT * FROM student; The Empty set (0.00 SEC)Copy the code
Note that here, unlike above, there is no data in case client B has not committed the transaction. Client B commits the transaction:
mysql> COMMIT;
Copy the code
Client A checks the student table again.
mysql> SELECT * FROM student; + - + -- -- -- -- -- -- + | | id name | + - + -- -- -- -- -- -- + | | 1 polo | + + -- -- -- -- -- -- - + 1 row in the set (0.00 SEC)Copy the code
So we have successfully read the customer.
As you can see from the above example, committed reads do not have the dirty read problem, but we can see that the same SELECT statement is executed twice in A transaction on client A with different results, so committed reads are also called unrepeatable reads. The same screening conditions may get different results.
Repeatable read
As the name suggests, solve the committed read non-repeatable read problem.
The example demonstrates that clients A and B set the isolation level to repeatable reads. First set the isolation level:
mysql> SET SESSION tx_isolation='REPEATABLE-READ'
Copy the code
Clients A and B start the transaction and view it
mysql> BEGIN; mysql> SELECT * FROM student; + - + -- -- -- -- -- -- + | | id name | + - + -- -- -- -- -- -- + | | 1 polo | + + -- -- -- -- -- -- - + 1 rows in the set (0.00 SEC)Copy the code
Client B updates Polo to Adam and commits the transaction
mysql> UPDATE student SET name='adam' WHERE id=1;
mysql> COMMIT
Copy the code
Client A checks the student table as follows:
mysql> SELECT * FROM student; + - + -- -- -- -- -- -- + | | id name | + - + -- -- -- -- -- -- + | | 1 polo | + + -- -- -- -- -- -- - + 1 rows in the set (0.00 SEC)Copy the code
The data on client A is not changed and there is no unrepeatable read problem.
Client A commits the transaction and looks at the Student table.
mysql> COMMIT; mysql> SELECT * FROM student; + - + -- -- -- -- -- -- + | | id name | + - + -- -- -- -- -- -- + | | 1 polo | + + -- -- -- -- -- -- - + 1 rows in the set (0.00 SEC)Copy the code
As you can see from the example above, the same content can be read twice. This level does not solve the illusion problem. However, MYSQL has added MVCC to repeatable reads to solve this problem. The effect of phantom reads cannot be demonstrated here.
So what is illusory? First, the repeatable read lock scope is for the current query, such as execution
mysql> SELECT * FROM student WHERE id>=1
Copy the code
The locked row is the row whose ID >=1. As another transaction executes and commits the following statement by default
mysql> INSERT INTO student (name) VALUES ('stephen');
Copy the code
The new row is not locked. Student is now read
mysql> SELECT * FROM student WHERE id>=1; + - + -- -- -- -- -- -- -- -- -- + | | id name | + - + -- -- -- -- -- -- -- -- -- + | 1 | polo | | 2 | Stephen | + - + -- -- -- -- -- -- -- -- -- + 2 rows in the set (0.00 SEC)Copy the code
Phantom reading appears. In addition to using MYSQL’s MVCC mechanism, you can solve this problem with serializable isolation levels.
serialization
Serialization is the highest isolation level and forces transactions to be executed serially. This level is only used when data consistency is critical and concurrency is not used.
The example demonstrates that clients A and B set the isolation level to serializable.
mysql> SET SESSION tx_isolation='SERIALIZABLE';
Copy the code
First, client A performs A query:
mysql> SELECT * FROM student WHERE id<4; + - + -- -- -- -- -- -- -- -- -- + | | id name | + - + -- -- -- -- -- -- -- -- -- + | 1 | polo | | 2 | Stephen | + - + -- -- -- -- -- -- -- -- -- + 2 rows in the set (0.00 SEC)Copy the code
Next, client B performs data addition:
mysql> INSERT INTO student (name) VALUES(‘yunteng’); Ok! INSERT statement is blocked because student (id<4) is locked. SQL > select student from student where id<3;
Summary figure
Isolation level | English | Dirty read | Unrepeatable read | Phantom read | Read lock |
---|---|---|---|---|---|
Uncommitted read | READ UNCOMMITTED | is | is | is | no |
Submit to read | READ COMMITTED | no | is | is | no |
Repeatable read | REPEATABLE READ | no | no | is | no |
serialization | SERIALIZABLE | no | no | no | is |
This is the end of the isolation level for transactions. The exact usage depends on the specific business scenario.