【mysql】-【Transaction】

Database transaction overview

Transaction is one of the important features that distinguishes the database from the file system. When we have a transaction, the database will always be executed. At the same time, we can also restore to a certain point in time through the transaction mechanism, which can ensure that the transaction has been submitted to the database. Modifications will not be lost due to system crashes

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.

basic concept

Transaction: A set of logical operation units that transform data from one state to another.
The principle of transaction processing: ensure that all transactions are executed as a unit of work. Even if a failure occurs, this execution method cannot be changed. When multiple operations are performed in a transaction, either all transactions are committed and the modifications are permanently saved; or the database management system abandons all modifications and the entire transaction is rolled back to initial state.

ACID properties of transactions

1. Atomicity: Atomicity means that a transaction is an indivisible unit of work, and either all is submitted or all fails and is rolled back.
2. Consistency: Consistency means that before and after a transaction is executed, the data changes from onelegal statuschange to anotherlegal status. This status is semantic rather than grammatical, and is related to specific business.

So what is legal data status? satisfypredetermined constraintsThe state is called the 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.

3. Isolation: The isolation of a transaction means that the execution of a transaction cannot be interfered by other transactions. That is, the operations and data used within a transaction are isolated from other concurrent transactions. Can't 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 ACCOUNT SET balance = balance - 10 WHERE id = 1; #此时这条DML操作是一个独立的事务
# 服务器宕机
UPDATE ACCOUNT SET balance = balance + 10 WHERE id = 2; #此时这条DML操作是一个独立的事务

These two SQLs are independent transactions. If the server goes down after executing the first one, then the money transferred out of the account will be less, but the money transferred into the account will not change. 4. Durability: Durability refers to
Insert image description here
a transaction Once submitted, its changes to the data in the database are permanent, and subsequent other operations and database failures should not have any impact on it.

Persistence is achieved throughtransaction logTo guarantee. The log includesredo logandRollback log. 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.

5. Summary: ACID is the four major characteristics of transactions. Among these four characteristics, atomicity is the foundation, isolation is the means, consistency is the constraint, and durability is our goal.

A database transaction is actually one or more database operations that need to ensure atomicity, isolation, execution, and durability that the database designer calls a transaction for the sake of convenience.

transaction status

We now know that a transaction is an abstract concept, which actually corresponds to one or more database operations. MySQL roughly divides transactions into several states based on the different stages of execution of these operations:

  1. Active: When the database operation corresponding to the transaction is being executed, we say that the transaction is in an active state.
  2. Partially committed: When the last operation in a transaction is completed, but because the operations are executed in memory and the impact is not flushed to disk, we say that the transaction is in a partially committed state.
  3. Failed: When a transaction is in an active or partially committed 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 the current transaction may have been artificially stopped. When a transaction is executed, we say that the transaction is in a failed state.
  4. Aborted: If part of the transaction is executed and becomes a failed 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 rollback. When the rollback operation is completed, that is, the database is restored to the state before the transaction was executed, we say that the transaction is in an aborted state.
    Insert image description here

How to use transactions

There are two ways to use transactions: explicit transactions and implicit transactions

explicit transaction

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

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

START TRANSACTIONWhat’s special about statements BEGINis that they can be followed by several modifiers:

  1. READ ONLY: identifies the current transaction as aread-only transaction, that is, the database operations belonging to this transaction can only read data, but cannot modify data.

In read-only transactions, only data in tables that can be accessed by other transactions is not allowed to be modified. For temporary tables (tables we create using create tmeporary table), since they are only visible in the current session, only In fact, read transactions can also add, delete, modify, and query temporary tables.

  1. READ WRITE: Identifies that the current transaction is aRead and write transactions, that is, the database operations belonging to this transaction can both read data and modify data.
  2. WITH CONSISTENT SNAPSHOT: Start consistent reading.
# 开启一个只读事务
start transaction read only

#开启只读事务和一致性读
start transaction read only, WITH CONSISTENT SNAPSHOT

Notice:

  1. READ ONLY and READ WRITE are used to set the so-called transaction access mode, which is whether to access the data in the database in a read-only or read-write manner. The access mode of a transaction cannot be set to read-only or read-write at the same time. , so you cannot put READ ONLY and READ WRITE after start transaction at the same time.
  2. If we do not explicitly specify the access mode of the transaction, then the access mode of the transaction is read-write mode

Step 2: A series of operations in a transaction (mainly DML, excluding DDL)
Step 3: Commit the transaction or abort the transaction (i.e. roll back the transaction)

# 提交事务。当提交事务后,对数据库的修改是永久性的。
mysql> COMMIT;

# 回滚事务。即撤销正在进行的所有没有提交的修改
mysql> ROLLBACK;

# 将事务回滚到某个保存点。
mysql> ROLLBACK TO [SAVEPOINT]

In fact, the related operations of SAVEPOINT are:

# 在事务中创建保存点,方便后续针对保存点进行回滚。一个事务中可以存在多个保存点
SAVEPOINT 保存点名称

# 删除某个保存点
release savepoint 保存点名称

There may be many operations in a transaction. If you make a mistake in the last step, the rollback will be rolled back to before the transaction was executed. If you want to roll back to a certain position in the transaction, you can use savepoint.

implicit transaction

There is a system variable in MySQL autocommit:

mysql> SHOW VARIABLES LIKE 'autocommit';#默认是ON

Insert image description here
Insert image description here

UPDATE ACCOUNT SET balance = balance - 10 WHERE id = 1; #此时这条DML操作是一个独立的事务

UPDATE ACCOUNT SET balance = balance + 10 WHERE id = 2; #此时这条DML操作是一个独立的事务,也就是说,执行完这一行代码,会默认有个commit提交

Of course, if we want to turn off this automatic submission function, we can use one of the following two methods:

  1. Explicitly use the START TRANSACTION or BEGIN statement to start a transaction. In this way, the automatic commit function will be temporarily turned off before this transaction is committed or rolled back.
#方式1:我们在autocommit为true的情况下,使用start transaction 或begin开启事务,那么DML操作就不会自动提交数据
START TRANSACTION;
UPDATE ACCOUNT SET balance = balance - 10 WHERE id = 1;
UPDATE ACCOUNT SET balance = balance + 10 WHERE id = 2; 
COMMIT; #或rollback;
  1. Set the value of the system variable autocommit to OFF, like this:
SET autocommit = OFF;# 针对于DML操作是有效的,对DDL操作是无效的。
#或
SET autocommit = 0;

# 设置完成后,执行以下三行代码就是提交一个事务
UPDATE ACCOUNT SET balance = balance - 10 WHERE id = 1;
UPDATE ACCOUNT SET balance = balance + 10 WHERE id = 2; 
COMMIT; #或rollback;

When the auto-commit function is turned off, the multiple statements we write belong to the same transaction until we explicitly write a commit statement to commit the transaction, or explicitly write a rollback statement to roll back the transaction. Lose

Oracle does not automatically commit by default and requires a handwritten commit command, while MySQL automatically commits by default.

Implicitly submitting data

Situations not controlled by the autocommit keyword
Insert image description here
Insert image description here
Insert image description here

Examples of using transactions

Case number one

SET autocommit = TRUE; #开启自动提交,默认就已经开启了自动提交,但是我们前面的操作可能把他关了,所以这里再打开一下
#举例1: commit 和 rollback
USE atguigudb2;
#情况1:
CREATE TABLE user3(NAME VARCHAR(15) PRIMARY KEY);

SELECT * FROM user3;

BEGIN;# 当autocommit = TRUE时,使用BEGIN开启事务
INSERT INTO user3 VALUES('张三'); #此时不会自动提交数据
COMMIT;# 提交事务(回滚到这里)

BEGIN; #开启一个新的事务
INSERT INTO user3 VALUES('李四'); #此时不会自动提交数据
INSERT INTO user3 VALUES('李四'); #受主键的影响,不能添加成功
ROLLBACK;# 回滚到最近一个commit那里,此时数据库只有“张三”一条数据

SELECT * FROM user3;

Case 2

#情况2:
TRUNCATE TABLE user3;  # 清空数据
#DDL操作会自动提交数据,不受autocommit变量的影响。
SELECT * FROM user3;

BEGIN;
INSERT INTO user3 VALUES('张三'); #此时不会自动提交数据
COMMIT;

INSERT INTO user3 VALUES('李四');# 默认情况下(即autocommit为true),DML操作也会自动提交数据。(回滚到这里)
INSERT INTO user3 VALUES('李四'); #事务的失败的状态,受主键的影响,不能添加成功

ROLLBACK;# 回滚到上一个commit,事务失败的状态由此变为中止的状态。此时数据库有“张三”、“李四”两条数据

SELECT * FROM user3;

Case three

TRUNCATE TABLE user3;

SELECT * FROM user3;

SELECT @@completion_type;# 查询结果:NO_CHAIN,没有链式行为

SET @@completion_type = 1;# 开启链式行为

BEGIN;
INSERT INTO user3 VALUES('张三'); 
COMMIT;

SELECT * FROM user3;# 此时数据库只有“张三”一条数据

INSERT INTO user3 VALUES('李四');
INSERT INTO user3 VALUES('李四'); #受主键的影响,不能添加成功

ROLLBACK;

SELECT * FROM user3;# 此时数据库只有“张三”一条数据

Insert image description here

Case 4: Experience INNODB and MyISAM

CREATE TABLE test1(i INT) ENGINE = INNODB;

CREATE TABLE test2(i INT) ENGINE = MYISAM;

#针对于innodb表
BEGIN# 开启一个事务
INSERT INTO test1 VALUES (1);# 插入一条数据
ROLLBACK;# 回滚

SELECT * FROM test1;# 数据库没有数据


#针对于myisam表:不支持事务
BEGIN# 开启一个事务
INSERT INTO test2 VALUES (1);# 插入一条数据
ROLLBACK;# 回滚

SELECT * FROM test2;# 数据还在,所以myisam不支持事务

Case 5: Experience savepoint

CREATE TABLE user3(NAME VARCHAR(15),balance DECIMAL(10,2));

BEGIN
INSERT INTO user3(NAME,balance) VALUES('张三',1000);
COMMIT;

SELECT * FROM user3;


BEGIN;
UPDATE user3 SET balance = balance - 100 WHERE NAME = '张三';

UPDATE user3 SET balance = balance - 100 WHERE NAME = '张三';

SAVEPOINT s1;#设置保存点

UPDATE user3 SET balance = balance + 1 WHERE NAME = '张三';

ROLLBACK TO s1; #回滚到保存点


SELECT * FROM user3;

ROLLBACK; #回滚操作

SELECT * FROM user3;

Rolling back to the savepoint is not the aborted state of the transaction. If there are 5 operations in a transaction, after executing the first two operations, it is sure that there is no problem. I set a savepoint. If the subsequent operation goes wrong, I can roll back to This savepoint ensures that my first two operations were executed correctly, but rolling back to the savepoint is not the aborted state of the transaction. After you roll back to the savepoint, you must either rollback to before the transaction was executed, or continue to write code and perform operations. , execute the remaining three operations, and commit after confirming that they are correct.

Common categories of transactions

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

  1. Flat Transactions: We usually use begin, commit and rollback.
  2. Flat Transactions with Savepoints: Flat transactions using savepoint
  3. Chained Transactions: A transaction is composed of multiple sub-transactions chained
  4. Nested Transactions: A transaction nests multiple sub-transactions
  5. Distributed Transactions
    Insert image description here
    Insert image description here

transaction isolation level

MySQL is a client/server 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 isolation characteristics. In theory, when a transaction accesses a certain data, other transactions should be queued. Only after the transaction is submitted, other transactions can continue to access the data. However, this has a great impact on performance. We not only want to maintain the isolation of transactions, but also want the server to have as high a performance as possible when processing multiple transactions that access the same data. It depends on the trade-off between the two.

data preparation

1. Create a table

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

2. Insert a piece of data

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

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 that access the same data are not guaranteed to be executed serially (that is, there is no guarantee that one will be executed before the other is executed).

脏写( Dirty Write )

For two transactions, Session A and Session B, if transaction Session A modifies the data modified by another uncommitted transaction, Session B, it means that a dirty write has occurred.
Insert image description here

Dirty Read

For two transactions, Session A and Session B, Session A reads fields that have been updated by Session B but have not yet been committed. If Session B is rolled back later, the content read by Session A will be temporary and invalid.
Insert image description here
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 Dirty reading.

Non-Repeatable Read

For two transactions, Session A and Session B, Session A reads a field, and then Session B updates the field. After Session A reads the same field again, the value is different. That means a non-repeatable read occurred.
Insert image description here
We submitted several implicit transactions in Session B (note that it is an implicit transaction, which means that the transaction is submitted when the statement ends). These transactions have modified the value of the column name of the record whose studentno column is 1. Each transaction is submitted. Afterwards, if all transactions in Session A can view the latest value, this phenomenon is also called non-repeatable read.

Phantom

For two transactions, Session A and Session B, Session A reads a field from a table, and then Session B inserts some new rows into the table. Later, if Session A reads the same table again, there will be a few more rows. That means phantom reading has occurred.
Insert image description here
The transaction in Session A first queries the table student based on the condition studentno > 0, and obtains the record with the name column value 'Zhang San'; then an implicit transaction is submitted in Session B, which inserts a record into the table student New record; later, 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 phantom reading. We call the newly inserted records phantom records.
Insert image description here

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. We will rank these problems according to their severity: 脏写>脏读>不可重复读>幻读. 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. There are 4 isolation levels established in the SQL standard:

  1. 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. (generally not used)
  2. READ COMMITTED: Read committed, which satisfies the simple definition of isolation:A transaction can only see changes made by the committed transaction. This is the default isolation level for most database systems (such as Oracle, but not the MySQL default). Dirty reads can be avoided, but the problems of non-repeatable reads and phantom reads still exist.
  3. 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. (MySQL default)
  4. 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. (Oracle support)

The SQL standard stipulates that for different isolation levels, concurrent transactions can cause problems of different severity. The specific situation is as follows: Why is
Insert image description here
dirty writing 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

Four isolation levels supported by MySQL

Insert image description here
Insert image description here

How to set the isolation level of a transaction

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

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

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

2. Regarding the impact of using GLOBAL or SESSION when setting:

  1. Use the GLOBAL keyword (affects global scope):
SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;
#或
SET GLOBAL TRANSACTION_ISOLATION = 'SERIALIZABLE';

Then: the current existing session is invalid; it only takes effect on the session generated after the statement is executed.

  1. Use the SESSION keyword (affects session scope):
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
#或
SET SESSION TRANSACTION_ISOLATION = 'SERIALIZABLE';

Then: it is valid for all subsequent transactions of 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 it will not affect the currently executing transaction

The database stipulates multiple 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.

Examples of different isolation levels

read-uncommittedRead uncommitted

Case number one

Insert image description here
Set the isolation level of the two transactions to uncommitted read:
Please add image description
then transaction one starts a transaction, in which the data it updates is not submitted. Transaction
Please add image description
two can find this data ,
Please add image description
and transaction one is rolled back,
Please add image description
but transaction two The data just found is dirty data

Case 2

Zhang San transfers 100 yuan to Li Si. Transaction 1 opens the transaction and performs this operation, but he does not submit:
Please add image description
Then transaction 2 query finds that Zhang San has transferred 100 yuan to Li Si, but Li Si does not want this. 100, so he transferred it back to Zhang San (to transfer back, he needed to execute two SQLs, one for himself -100, the other for Zhang San +100, and the one executed first here was -100). After executing the last update statement, it got stuck. Here, this is because transaction one has not committed the transaction at this time and is still occupied. The database is locked, so the update of transaction two is waiting here. Then in
Please add image description
transaction one, Zhang San does not want to transfer money to Li Si, and transaction one is rolled back. After
Please add image description
transaction one is rolled back, the update statement that transaction two is waiting for (the one where Li Si transfers 100 yuan to Zhang San) is also executed. After the execution, transaction two continues to execute Zhang San's +100 SQL and commit the final database Please add image description
. It is unreasonable that Zhang San’s account has 200 and Li Si’s account has -100.

read-committedread-committed

Restore the data (clear the table and add data), and then set the transaction level to read-committed:
Please add image description
In transaction two, you also need to set the transaction level to read-committed:
Please add image description
Then in transaction one, open the transaction and operate the data (reduce Zhang San's account by 50 block), without committing or rolling back.
Please add image description
Then transaction two starts the transaction and checks the data. It has not changed. This is equivalent to avoiding dirty reads.
Please add image description
Then transaction one commits
Please add image description
and transaction two continues to query in the original transaction. The data is the latest. Changed data:
Insert image description here
Transaction two starts a transaction to view the data, and another transaction changes the data. What transaction two finds is the latest data, which is non-repeatable reading. Then transaction two commits the transaction to view the data
Insert image description here

repeatable-read repeatable read

On the basis of the above, we continue to demonstrate repeatable read, set the transaction level of both transactions to repeatable read, Please add image description
and then open a transaction in transaction one, so that Zhang San’s account is reduced by 10.
Please add image description
Transaction two opens a transaction and executes the query. Zhang San’s account has not changed, it is still 50,
Insert image description here
and then transaction one submitted the transaction Please add image description
. Transaction two queried in the original transaction, Zhang San’s account has not changed, it is still 50.
Please add image description
Then transaction two submitted the transaction, and then queried, the data became the latest data.
Please add image description
Repeatable reading: Transaction 1 opens a transaction to operate data, and transaction 2 opens a transaction to query data. No matter how transaction 1 changes the data, no matter whether transaction 1 commits or not, the data found by the same transaction in transaction 2 will always be the same.

phantom reading

In transaction two, a transaction is opened, and the number of data with id=3 is queried, but no data is found. In
Please add image description
transaction one, a transaction is opened, and the data with id=3 is inserted into it and submitted.
Please add image description
Then transaction two queries the data with id=3 in the original transaction. Still couldn't find it out, and then transaction two inserted the data with id=3, and an error was reported.
Please add image description
This is a phantom read.
Please add image description
Finally, transaction two is rolled back and Please add image description
the serialized isolation level can be used to solve the phantom read problem: after transaction two starts the transaction and executes the query for the data with id=3, this data is locked, and then transaction one inserts the data with id=3. The data will be stuck, and the operation of transaction one will be continued after transaction two is committed (if transaction one does not insert the data with id=3, it will be executed smoothly)

Common categories of transactions

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

  1. Flat Transactions
  2. Flat Transactions with Savepoints Chained Transactions
  3. Nested Transactions
  4. Distributed Transactions

Guess you like

Origin blog.csdn.net/CaraYQ/article/details/129351650