MySQL Basics (32) Transaction Basics

1 Overview of database transactions

1.1 Storage engine support

SHOW ENGINEScommand to see what storage engines are currently supported by MySQL and whether these storage engines support transactions.

Insert image description here
It can be seen that in MySQL, only InnoDB supports transactions.

1.2 Basic concepts

事务: A set of logical operation units that transform data from one state to another.
事务处理的原则: Ensure that all transactions are 一个工作单元executed as , even if a failure occurs, this execution method cannot be changed. When multiple operations are performed in a transaction, either all transactions are committed ( commit), and then these modifications 永久are saved in place; or the database management system rolls back ( ) 放弃all the transactions made 修改and the entire transaction rollbackto the original state.

1.3 ACID characteristics of transactions

  • Atomicity:
    Atomicity means that a transaction is an indivisible unit of work, and either all is committed or all fails and is rolled back.

  • Consistency:
    By definition, consistency refers to the 合法性状态transformation of data from one to another before and after a transaction is executed 合法性状态. This status is 语义上not grammatical, but related to specific business.

So what is legal data status? The state that satisfies 预定的约束is called a legal state. In layman's terms, this state is defined by you (such as satisfying constraints in the real world). If this state is met, the data is consistent; if this state is not met, the data is inconsistent! If an operation in the transaction fails, the system will automatically cancel the currently executing transaction and return to the state before the transaction operation.

  • Isolation:
    The isolation of a transaction refers to the execution of a transaction 不能被其他事务干扰, that is, the operations and data used within a transaction are isolated from other concurrent transactions, and concurrently executed transactions cannot interfere with each other.
    What happens if isolation cannot be guaranteed? Assume that account A has 200 yuan and account B has 0 yuan. Account A transfers money to account B twice, each amount is 50 yuan, and is executed in two transactions respectively. If isolation cannot be guaranteed, the following situations will occur:
UPDATE accounts SET money = money - 50 WHERE NAME = 'AA';

UPDATE accounts SET money = money + 50 WHERE NAME = 'BB';

Insert image description here

  • Durability: Durability
    means that once a transaction is committed, the changes it makes to the data in the database are that 永久性的subsequent operations and database failures should not have any impact on it.
    Durability is 事务日志ensured by . The log includes 重做日志and 回滚日志. When we modify data through transactions, we will first record the database change information into the redo log, and then modify the corresponding rows in the database. The advantage of this is that even if the database system crashes, after the database is restarted, the redo logs that have not been updated in the database system can be found and re-executed, thus making the transaction durable.

1.4 Status of transactions

We now know 事务that is an abstract concept, which actually corresponds to one or more database operations. MySQL roughly divides it into 事务several states according to the different stages of execution of these operations:

  • When the database operation corresponding to an active (active)
    transaction is being executed, we say that the transaction is in 活动的the status.
  • Partially committed (partially committed)
    When the last operation in the transaction is completed, but because the operations are executed in memory, the impact is not flushed to the disk, we say that the transaction is in a partially committed state.
  • Failed (failed)
    When the transaction is in 活动的or 部分提交的state, it may have encountered some errors (errors in the database itself, operating system errors or direct power outages, etc.) and cannot continue to execute, or artificially stopped the execution of the current transaction, we will Says the transaction is in 失败的status.
  • Aborted (aborted)
    If part of the transaction is executed and becomes 失败的the state, then the modified operations in the transaction need to be restored to the state before the transaction was executed. In other words, it is to undo the impact of the failed transaction on the current database. We call this undoing process 回滚. When 回滚the operation is completed, that is, the database is restored to the state before the transaction was executed, we say that the transaction is in the 中止的state.
    Example:
    UPDATE accounts SET money = money - 50 WHERE NAME = 'AA';
    
    UPDATE accounts SET money = money + 50 WHERE NAME = 'BB';
    
  • Committed (Committed)
    When a 部分提交的transaction in the state has uploaded all modified data 同步到磁盘, we can say that the transaction is in 提交的the state.

A basic state transition diagram looks like this:
Insert image description here

2 How to use transactions

There are two ways to use transactions, namely 显式事务and 隐式事务.

2.1 Display transactions

Step 1 : START TRANSACTIONAlternatively BEGIN, the effect is to explicitly start a transaction.

mysql> BEGIN;
#或者
mysql> START TRANSACTION;

START TRANSACTIONWhat's special about the statement BEGINis that it can be followed by several 修饰符:

READ ONLY: Indicates that the current transaction is one 只读事务, that is, the database operations belonging to this transaction can only read data, but cannot modify data.

READ WRITE: Indicates that the current transaction is one 读写事务, that is, the database operations belonging to this transaction can both read data and modify data.

WITH CONSISTENT SNAPSHOT: Start consistent reading.

Step 2 : A series of operations in a transaction (mainly DML, not DDL)

Step 3 : Commit the transaction or abort the transaction (i.e. roll back the transaction)

# 提交事务。当提交事务后,对数据库的修改是永久性的。
mysql> COMMIT;
# 回滚事务。即撤销正在进行的所有没有提交的修改
mysql> ROLLBACK;
# 将事务回滚到某个保存点。
mysql> ROLLBACK TO [SAVEPOINT]

2.2 Implicit transactions

There is a system variable in MySQL autocommit:

mysql> SHOW VARIABLES LIKE 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | ON |
+---------------+-------+
1 row in set (0.01 sec)

Of course, if we want to turn off this 自动提交function, we can use one of the following two methods:

  • Explicitly use START TRANSACTIONthe or BEGINstatement to start a transaction. In this way, the automatic commit function will be temporarily turned off before this transaction is committed or rolled back.

  • Set the value of the system variable autocommitto OFF, like this:

    SET autocommit = OFF;
    #或
    SET autocommit = 0;
    

2.3 The case of implicit data submission

  • Data definition language (abbreviated as: DDL)

  • Transaction control or statements about locks

    • When we use the START TRANSACTION or BEGIN statement to open another transaction before a transaction is committed or rolled back, the previous transaction will be implicitly committed. Right now:
    • The current value of the autocommit system variable is OFF. When we manually turn it to ON, the transaction to which the previous statement belongs will also be implicitly committed.
    • Using locking statements such as LOCK TABLES and UNLOCK TABLES will also implicitly commit the transaction to which the previous statement belongs.
  • statement to load data

  • Some statements about MySQL replication

  • Some other sentences

2.4 Usage example 1: Submit and rollback

Let's take a look at the final processing result of the following transaction in MySQL's default state.

Case 1:

CREATE TABLE user(name varchar(20), PRIMARY KEY (name)) ENGINE=InnoDB;
BEGIN;
INSERT INTO user SELECT '张三';
COMMIT;
BEGIN;
INSERT INTO user SELECT '李四';
INSERT INTO user SELECT '李四';
ROLLBACK;
SELECT * FROM user;

Running results (1 row of data):

mysql> commit;
Query OK, 0 rows affected (0.00)
mysql> BEGIN;
Query OK, 0 rows affected (0.00)
mysql> INSERT INTO user SELECT '李四';
Query OK, 1 rows affected (0.00)
mysql> INSERT INTO user SELECT '李四';
Duplicate entry '李四' for key 'user.PRIMARY'
mysql> ROLLBACK;
Query OK, 0 rows affected (0.01)
mysql> select * from user;
+--------+
| name |
+--------+
| 张三 |
+--------+
1 行于数据集 (0.01)

Case 2:

CREATE TABLE user (name varchar(20), PRIMARY KEY (name)) ENGINE=InnoDB;
BEGIN;
INSERT INTO user SELECT '张三';
COMMIT;
INSERT INTO user SELECT '李四';
INSERT INTO user SELECT '李四';
ROLLBACK;

Running results (2 rows of data):

mysql> SELECT * FROM user;
+--------+
| name |
+--------+
| 张三 |
| 李四 |
+--------+
2 行于数据集 (0.01)

Case 3:

CREATE TABLE user(name varchar(255), PRIMARY KEY (name)) ENGINE=InnoDB;
SET @@completion_type = 1;
BEGIN;
INSERT INTO user SELECT '张三';
COMMIT;
INSERT INTO user SELECT '李四';
INSERT INTO user SELECT '李四';
ROLLBACK;
SELECT * FROM user;

Running results (1 row of data):

mysql> SELECT * FROM user;
+--------+
| name |
+--------+
| 张三 |
+--------+
1 行于数据集 (0.01)

When we set autocommit=0, no matter whether we use START TRANSACTION or BEGIN to start the transaction, we need to use COMMIT to commit to make the transaction effective, and use ROLLBACK to roll back the transaction.

When we set autocommit=1, each SQL statement will be automatically submitted. But at this time, if you use START TRANSACTION or BEGIN to explicitly start the transaction, then the transaction will only take effect when COMMIT is issued, and will be rolled back when ROLLBACK is issued.

3 transaction isolation levels

MySQL is an 客户端/服务器architecture software. For the same server, several clients can connect to it. After each client connects to the server, it can be called a session ( ) Session. Each client can issue a request statement to the server in its own session. A request statement may be part of a transaction, that is, the server may process multiple transactions at the same time. Transactions have 隔离性the characteristics of . In theory, when a certain transaction is 对某个数据进行访问, other transactions should proceed 排队. Only after the transaction is submitted, other transactions can continue to access this data. But in this case 性能影响太大, we want to maintain the isolation of transactions, but also want the server to handle multiple transactions that access the same data 性能尽量高些. It depends on the trade-off between the two.

3.1 Data preparation

We need to create a table:

CREATE TABLE student (
studentno INT,
name VARCHAR(20),
class varchar(20),
PRIMARY KEY (studentno)
) Engine=InnoDB CHARSET=utf8;

Then insert a piece of data into this table:

INSERT INTO student VALUES(1, '小谷', '1班');

The data in the table now looks like this:

mysql> select * from student;
+-----------+--------+-------+
| studentno | name | class |
+-----------+--------+-------+
| 1 | 小谷 | 1|
+-----------+--------+-------+
1 row in set (0.00 sec)

3.2 Data concurrency issues

How do we make a trade-off between transaction isolation and concurrency? 不保证串行执行Let’s first look at the problems that may arise when transactions access the same data (that is, after executing one and then executing the other):

1. Dirty Write (Dirty Write)
For two transactions Session A and Session B, if transaction Session A has data from 修改了another 未提交transaction Session B 修改过, it means that it has occurred脏写

2. Dirty Read (Dirty Read)
For two transactions, Session A and Session B, Session A contains fields that 读取have been read by Session B 更新but have not yet been read. 没有被提交After that, if Session B 回滚, the content read by Session A will 临时且无效be.

Session A and Session B each open a transaction. The transaction in Session B first updates the name column of the record with studentno listed as 1 to 'Zhang San', and then the transaction in Session A queries the record with studentno listed as 1. , if the value of column name is read as 'Zhang San', and the transaction in Session B is rolled back later, then the transaction in Session A is equivalent to reading non-existent data. This phenomenon is called 脏读.

3. Non-Repeatable Read (Non-Repeatable Read)
For two transactions, Session A and Session B, Session A 读取reads a field, and then Session B 更新reads the field. 再次读取Then the same field in Session A , 值就不同too. That means a non-repeatable read occurred.

We have submitted several transactions in Session B 隐式事务(note that they are implicit transactions, which means that the transaction is submitted after the statement is completed). These transactions have modified the value of the column name of the record whose studentno column is 1. After each transaction is submitted, if All transactions in Session A can view the latest value. This phenomenon is also called 不可重复读.

4. Phantom reading (Phantom)
For two transactions, Session A and Session B, Session A 读取retrieves a field from a table, and then Session B inserts some new rows into the table. Afterwards, if Session A 再次读取is in the same table, there will be a few more rows. That means phantom reading has occurred.

The transaction in Session A first queries the table student based on the condition studentno > 0, and obtains a record with the name column value 'Zhang San'; then a new record is submitted in Session B, and the transaction inserts a new record into the table student 隐式事务; Afterwards, the transaction in Session A queries the table student based on the same condition studentno > 0, and the result set contains the record newly inserted by the transaction in Session B. This phenomenon is also called 幻读. We call those newly inserted records 幻影记录.

3.3 Four isolation levels in SQL

The above introduces some problems that may be encountered during the execution of several concurrent transactions. These problems are divided into priorities. Let us rank these problems according to their severity:

Dirty write > Dirty read > Non-repeatable read > Phantom read

Our willingness to give up part of the isolation in exchange for part of the performance is reflected here: setting up some isolation levels. The lower the isolation level, the more concurrency problems will occur. SQL标准4 have been established 隔离级别:

  • READ UNCOMMITTED: Read uncommitted. At this isolation level, all transactions can see the execution results of other uncommitted transactions. Dirty reads, non-repeatable reads, and phantom reads cannot be avoided.
  • READ COMMITTED: Read committed, which meets the simple definition of isolation: a transaction can only see changes made by committed transactions. This is the default isolation level for most database systems (but not the MySQL default). Dirty reads can be avoided, but the problems of non-repeatable reads and phantom reads still exist.
  • REPEATABLE READ: Repeatable reading. After transaction A reads a piece of data, transaction B modifies and commits the data. Then transaction A reads the data again and the original content is read. Dirty reads and non-repeatable reads can be avoided, but the problem of phantom reads still exists. This is MySQL's default isolation level.
  • SERIALIZABLE: Serializable, ensuring that transactions can read the same rows from a table. During the duration of this transaction, other transactions are prohibited from performing insert, update, and delete operations on the table. All concurrency problems can be avoided, but performance is very low. Dirty reads, non-repeatable reads and phantom reads can be avoided.

SQL标准It is stipulated in the document that for different isolation levels, concurrent transactions can cause problems of different severity. The specific situation is as follows:
Insert image description here脏写Why is it not involved? Because the problem of dirty writes is so serious, dirty writes are not allowed to occur regardless of the isolation level.

Different isolation levels have different phenomena, and have different locks and concurrency mechanisms. The higher the isolation level, the worse the concurrency performance of the database. The relationship between the four transaction isolation levels and concurrency performance is as follows:
Insert image description here

3.4 Four isolation levels supported by MySQL

The default isolation level of MySQL is REPEATABLE READ. We can manually modify the isolation level of the transaction.

# 查看隔离级别,MySQL 5.7.20的版本之前:
mysql> SHOW VARIABLES LIKE 'tx_isolation';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.00 sec)
# MySQL 5.7.20版本之后,引入transaction_isolation来替换tx_isolation
# 查看隔离级别,MySQL 5.7.20的版本及之后:
mysql> SHOW VARIABLES LIKE 'transaction_isolation';
+-----------------------+-----------------+
| Variable_name | Value |
+-----------------------+-----------------+
| transaction_isolation | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set (0.02 sec)
#或者不同MySQL版本中都可以使用的:
SELECT @@transaction_isolation;

3.5 How to set the isolation level of a transaction

Modify the isolation level of the transaction through the following statement:

SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL 隔离级别;
#其中,隔离级别格式:
> READ UNCOMMITTED
> READ COMMITTED
> REPEATABLE READ
> SERIALIZABLE

or:

SET [GLOBAL|SESSION] TRANSACTION_ISOLATION = '隔离级别'
#其中,隔离级别格式:
> READ-UNCOMMITTED
> READ-COMMITTED
> REPEATABLE-READ
> SERIALIZABLE

Regarding the impact of using GLOBAL or SESSION when setting up:

  • Use GLOBALkeyword (affects at global scope):

    SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    #或
    SET GLOBAL TRANSACTION_ISOLATION = 'SERIALIZABLE';
    

    but:

    • The currently existing session is invalid
    • Only works on sessions generated after executing this statement
  • Use SESSIONthe keyword (affects session scope):

    SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    #或
    SET SESSION TRANSACTION_ISOLATION = 'SERIALIZABLE';
    

    but:

    • Valid for all subsequent transactions in the current session
    • If executed between transactions, it is valid for subsequent transactions
    • This statement can be executed in the middle of an already opened transaction, but will not affect the currently executing transaction.

Summary:
The database stipulates a variety of transaction isolation levels. Different isolation levels correspond to different degrees of interference. The higher the isolation level, the
better the data consistency, but the weaker the concurrency.

3.6 Examples of different isolation levels

Demo 1. Read uncommitted dirty read

Set the isolation level to Uncommitted Read:
Insert image description here
The execution process of Transaction 1 and Transaction 2 is as follows:
Insert image description here
Demo 2: Read Committed
Insert image description here Set the isolation level to Repeatable Read, the execution process of the transaction is as follows:
Insert image description here
Demo 4: Phantom Read
Insert image description here

4. Common classifications of transactions

From the perspective of transaction theory, transactions can be divided into the following types:

  • Flat Transactions
  • Flat Transactions with Savepoints
  • Chained Transactions
  • Nested Transactions
  • Distributed Transactions

Guess you like

Origin blog.csdn.net/zhufei463738313/article/details/130660304