1. What are transactions
A transaction is a logical (non-divisible) unit in a database management system (DBMS) execution that consists of a finite sequence of database operations (multiple DML statements, select statements that do not contain transactions) that either all succeed or all fail.
For example, if A transfers money to B, A’s account will be -1000 yuan, and B’s account will be +1000 yuan. The two update statements must be executed as A whole, otherwise A will deduct money, and B will not add money. The transaction then guarantees that all changes to account A and account B will occur at once, or none at all.
2. Transaction features
Transactions have 4 attributes: Atomicity, Consistency, Isolation, Durability. These four properties are commonly referred to as ACID properties.
2.1 atomic
A transaction must be treated as an indivisible, minimal unit in which all operations in the entire transaction either commit successfully or fail. For a transaction, only a few operations cannot be performed.
For example: A transfers money to B, A deducts 500 yuan and B adds 500 yuan
The operation of the whole transaction is either all successful or all failed, so A cannot deduct money, but B does not increase. If atomicity is not guaranteed, consistency problems naturally arise.
2.2 consistency
Consistency means that a transaction transitions the database from one consistency state to another without compromising the integrity of the data in the database before and after the transaction.
If A transfers money to B, A deducts 500 yuan and B adds 500 yuan, the sum of the deducted money (-500) and the added money (+500) should add up to 0.
2.3 isolation,
The execution of a transaction cannot be interfered with by other transactions. That is, the operations and data used within a transaction are isolated from other concurrent transactions, and the concurrent transactions cannot interfere with each other.
What problems can arise if isolation is not guaranteed?
If A has 1000 at the beginning and B has no money, then A transfers money to B twice, 500 for the first time and 500 for the second time. If we call these two transfer operations T1 and T2 respectively, then under normal circumstances, the transfer should be done one by one, but there may be alternation in the database. Such as:
T1 | T2 |
---|---|
Read: A = 1000 | |
Read: A = 1000 | |
A – 500 = 500 | |
B + 500 = 500 | |
Read: B = 500 | |
A – 500 = 500 | |
B + 500 = 1000 |
So if we do this, A has 500 left, and B is already 1000, so we have 500 more.
2.4 persistence
Once a transaction commits, its changes are permanently stored in the database. Even if the system crashes, the submitted modification data will not be lost.
3. Transaction concurrency
As we know, MySQL is a client/server architecture software. For the same server, there can be several clients connected to it. After each client is connected to the server, it can be called a Session. Each client can issue a request statement to the server in its own session, and a request statement can be part of a transaction, meaning that it is possible for the server to process multiple transactions simultaneously.
As mentioned above, transactions have a property called isolation. In theory, when a transaction accesses a data, other transactions should queue up, and when the transaction commits, other transactions can continue to access the data. In this way, the execution of concurrent transactions becomes serial execution.
We want to maintain some isolation of transactions while allowing the server to handle as many transactions as possible accessing the same data. What kind of data problems might arise when we abandon isolation?
3.1 Isolation Level
MySQL has four transaction isolation levels, increasing in intensity. High isolation limits the number of transactions that can be executed in parallel, so some applications reduce isolation levels in exchange for greater throughput. Different service scenarios use different database transaction isolation. Some key services use high isolation levels to ensure data correctness.
MySQL > create transaction isolation levels
- Read Uncommitted: A transaction can Read data that is not committed by different transactions. In practical applications, dirty reads are generated. A transaction has Read data that is not committed by other transactions, but the data is rolled back.
- Read Committed: Transaction read other things have submitted data, read the latest data, so it will appear in the same transaction is not consistent the select read data, can appear not repeatable read, not repeatable read problem is we are in the same transaction execution exactly the same when the select statement may see different results.
- Repeatable Read: Mysql default isolation level, read many times the same data in the same transaction result is the same, solve the problem not repeatable read, read this level will be illusions, namely when the user read a range of data lines, another transaction and insert a new row in the scale, when the user read the scope of the data row again, will find that there is a new line.
- Serializable: The highest level of transaction isolation. Serializable forces transaction sequencing to block, avoids transaction conflicts, and solves all the problems mentioned above. It uses shared locks, which is inefficient in execution and can lead to a large number of timeout and lock switching competitions.
Note: MySQL’s default transaction isolation level is Repeatable Read.
To view the default isolation level:
SHOW VARIABLES LIKE 'transaction_isolation'; Or SELECT @ @ transaction_isolation;Copy the code
How do I set the isolation level for a transaction
SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL level;
Copy the code
There are four optional level values:
- READ UNCOMMITTED
- READ COMMITTED
- REPEATABLE READ
- SERIALIZABLE
When setting the isolation level of a transaction, you can place the GLOBAL keyword, SESSION keyword, or nothing after the SET keyword. This will have different effects on different scopes of transactions as follows:
Use the GLOBAL keyword (globally affected) :
SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;
Copy the code
Only the session generated after the statement is executed is valid. The existing session is invalid.
Use the SESSION keyword (affected at the SESSION scope) :
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
Copy the code
Valid for all subsequent transactions of the current session.
This statement can be executed in the middle of an already opened transaction, but does not affect the currently executing transaction. If executed between transactions, it is valid for subsequent transactions.
Neither keyword is used (only affects the next transaction after the statement is executed) :
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
Copy the code
Only valid for the next transaction to be started in the current session. After the next transaction completes, subsequent transactions revert to the previous isolation level. This statement cannot be executed in the middle of an already opened transaction, and an error will be reported.
If we want to change the default transaction isolation level when the server is started, we can change the value of the startup parameter transaction-ISOLATION. For example, we specify — transaction-Isolation =SERIALIZABLE when the server is started. The default isolation level of the transaction is changed from REPEATABLE READ to SERIALIZABLE.
3.2 Basic transaction syntax
instructions | operation |
---|---|
The transaction start | begin |
Transaction rollback | rollback |
Transaction commit | commit |
Create a new table to illustrate the problems caused by different isolation levels:
CREATE TABLE 'account' (' id 'bigint NOT NULL COMMENT' id ', 'name' varchar(30) DEFAULT NULL COMMENT 'iD ', 'money' decimal(12,2) DEFAULT NULL COMMENT 'account balance ', PRIMARY KEY (' id')) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;Copy the code
Initial data is as follows:
3.3 dirty read
When a transaction reads data that another transaction has modified but not committed, it is called a dirty read.
Open two session sessions and set the isolation level to read uncommitted:
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
Copy the code
1. Start A transaction T1 and read the current amount of A.
2, open another transaction T2, increase A’s amount by 500, but do not commit.
3. The query data in T1 is 1500.
If T2 is rolled back, the final value is 1000. If T1 is 1500 and performs operations before T2 is rolled back, dirty reads will occur.
T1 | T2 |
---|---|
BEGIN | |
SELECT money FROM account WHERE id = 1 | BEGIN |
UPDATE account SET money = money + 500 WHERE id = 1 | |
SELECT money FROM account WHERE id = 1 | |
ROLLBACK |
3.4 Unrepeatable Read
When the same record in a transaction is retrieved twice and the results obtained are different, this phenomenon is called non-repeatable reads.
Open two session sessions and set the isolation level to read committed:
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
Copy the code
1. Start A transaction T1 and read the current amount of A.
2, open another transaction T2, increase the amount of A by 500, commit.
3. For T1, the amount of A is 1500, and the two query results are different. T2 made changes to the record and committed successfully, which means that the modified record is visible to other transactions, so T1 reads money differently in both cases.
T1 | T2 |
---|---|
BEGIN | |
SELECT money FROM account WHERE id = 1 | BEGIN |
UPDATE account SET money = money + 500 WHERE id = 1 | |
COMMIT | |
SELECT money FROM account WHERE id = 1 | |
COMMIT |
3.5 phantom read
General explanation:
Transaction T1 performs the same select operation twice to obtain different data sets. This is not a magic read, it is a type of non-repeatable read (same as delete), and only occurs at r-U and R-C levels, which is not allowed in MySQL’s default RR isolation level.
In fact:
This is not to say that the result sets obtained by the two reads are different. The phantom read focuses on the fact that the data state represented by the result obtained by one SELECT operation cannot support subsequent business operations. Select whether a record exists, does not exist, and attempts to insert the record, but the record already exists and cannot be inserted.
Open two sessions and set the isolation level to repeatable read:
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
Copy the code
1. Start transaction T1 and query data whose name is A.
2. Open another transaction T2, add A new data named A and commit it.
3. If the same data is added to T1, an error will be reported. No data can be found in T1, but it is informed that the data already exists, resulting in a phantom read phenomenon.
Other scenarios:
Bank A opened A transaction window to check whether there was A “ayue” user in the current system, but found there was not. Bank B also opened A transaction window to check whether there was A “ayue” user in the current system. Bank A first created the “ayue” user and submitted it. Bank B must ensure data consistency in a transaction, so “AYue” could not be queried. As a result, the window of bank B thought that “AYue” had not been registered, so it created “ayue” user to register “Ayue” user, only to find that the system indicated that “ayue” user had been registered. But “ayue” is not found in this transaction, just like an illusion.
4. To summarize
MySQL isolation levels
Isolation level | Dirty read | Unrepeatable read | Phantom read |
---|---|---|---|
READ UNCOMMITTED | May occur | May occur | May occur |
READ COMMITTED | To solve | May occur | May occur |
REPEATABLE READ | To solve | To solve | May occur |
SERIALIZABLE | To solve | To solve | To solve |