MySQL database - MySQL transaction

1. Concept

A series of steps (operations) required to complete something. These operations either succeed or fail at the same time.

2. Basic operations of transactions

Zhang San and Li Si each have 1,000 yuan in their accounts. Now Zhang San transfers 500 yuan to Li Si.

-- 1 创建account表
create table tb_account(
id int(11) auto_increment,
user_name varchar(30) not null,
account_blance  int(11) not null, -- 账户余额
primary key (id)    
)ENGINE=INNODB,default charset =UTF8;

-- 2 插入数据
insert into tb_account(user_name,account_blance)
values('ZS',1000),('LS',1000);

-- 3 执行张三向李四转账500
-- ZS账户-500,LS账户+500
-- 下面两个update语句要么同时执行成功要么同时执行失败
-- 执行下列SQL语句会出现问题:张三的钱减少了,李四的钱没有加上。因为此时的两个update语句并没有使用事务来托管
update tb_account set account_blance=account_blance-500 where id=1;
-- 银行转帐异常情况:如机机房停电
update tb_account set account_blance=account_blance+500 where id=2;

3. Four Characteristics of Affairs

Atomicity : every step of the transaction cannot be divided again

Consistency : The accounts of Zhang San and Li Si have a total of 2,000 yuan. No matter how many transfers are made, the total amount remains unchanged.

Persistence : When a transaction is executed successfully (completed), the data will be persisted to the data file on the disk. For example, if the transfer is successful: Zhang San’s balance becomes 500, and Li Si’s balance becomes 1,500.

Isolation : Transaction A and transaction B operate on a piece of data at the same time and do not affect each other.

4. How to submit transactions,

1) Automatic submission

There is no need to write commit; the DML statement will be automatically submitted persistently.

2) Manual submission

--The query result is 1 for automatic submission and 0 for manual submission.

select @@autocommit;

-- Modify the submission method (change automatic submission to manual submission)

set @@autocommit = 0 ;

5. Basic operations of transactions

1 Start a transaction

start transaction;

2 Commit the transaction

commit;

3 Rollback transaction

rollback;

Note: Once you use start transaction; to open a transaction, automatic submission will be invalid.

  If all operations are executed normally use commit; commit the transaction

  When an exception occurs and a transaction is rolled back, the data (in this case, the tb_account table) is usually rolled back to the state before the transaction was started.

6. Transfer operation

-- 1 开启事务
start transaction;
-- 2 执行SQL语句
update tb_account set account_blance=account_blance-500 where id=1;
 手机转账异常情况:转账过程中手机没电了
update tb_account set account_blance=account_blance+500 where id=2;
-- 3 如果SQL语句全部执行成功就提交事务,如果其中任何一步执行失败,立刻回滚事务
-- 此时第一个update执行成功,第二个update语句执行失败了,并没有提交事务,查询结果如下:
select * from tb_account;
/*
+----+-----------+----------------+
| id | user_name | account_blance |
+----+-----------+----------------+
|  1 | ZS        |            500 |
|  2 | LS        |           1000 |
+----+-----------+----------------+
*/
-- 问题:张三账户的余额减少了,李四账户余额没有增加。这就是脏数据
-- 此时需要将脏数据回滚到开启事务之前
rollback;
-- 回滚完毕再次查询
select * from tb_account;
-- 此时事务回滚到开启之前的状态
/*
+----+-----------+----------------+
| id | user_name | account_blance |
+----+-----------+----------------+
|  1 | ZS        |           1000 |
|  2 | LS        |           1000 |
+----+-----------+----------------+
*/
-- 一个事务一旦开启了,在没有执行commit;或者rollback;之前事务不会结束
-- 相关面试题:工作中有没有用到事务?请解释事务的概念?不使用事务会发生什么问题?使用事务能够解决什么问题?解释事务的四大特征[隔离级别]?

7. Transaction isolation level

transaction isolation level

dirty read

non-repeatable read

phantom reading

read-uncommitted

yes

yes

yes

read-committed

no

yes

yes

Repeatable-read

no

no

yes

serializable

no

no

no

 Query isolation level

select @@tx_isolation

At work: Neither 1 nor 4 is used, only switching between 2 and 3

The default transaction isolation level of MySQL is 3, and the default isolation level of Oracle is 2.

SELECT @@global.tx_isolation; //查询全局事务
SELECT @@session.tx_isolation; //查询当前会话事务

set transaction isolation level level

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
//测试可以不用设置全局事务
SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
//(这个可以不用设,只设置上面一行就可以了进行测试了)

Dirty read:

One transaction (A) reads uncommitted data from another transaction (B) (breaking isolation).

  For example: Transaction A opens a transaction for transfer, and the DML statement is executed successfully but without commit; transaction B is opened in another window, and the Select statement is executed to read the tb_account data, and the read result is the data that transaction A has not submitted.

Non-repeatable reading:

The data read multiple times in the same transaction is inconsistent ( breaking the consistency, update and delete)

  For example: Transaction A opens a transaction for transfer, and the DML statement is executed successfully but without commit; Transaction B is opened in another window, and the Select statement is executed to read the tb_account data, and the read result is correct (1000, 1000).

  A transaction was submitted in transaction A. Then transaction B performs the Select operation again and the query result is correct (500,1500)

  Problem: Transaction B performed two select operations on the tb_account table in one transaction, and the query results of the two operations were inconsistent.

Phantom reading:

Transaction A inserts a piece of data and can use select to obtain the result. At this time, transaction B inserts a piece or a large amount of data almost at the same time. At this time, transaction A cannot see the update of transaction B (breaking the consistency, insert ).

read uncommitted dirty read test:

f67e3147f2ff45fbbed5c9a1edb7c4f5.png

 When a transaction is started, another transaction can read the statement updates of this transaction without committed submission.

How to solve the dirty read problem? Modify transaction isolation level: read committed

set session transaction isolation level read committed;

5daaa016c45a40418485f6987095cc4c.png

How to solve the non-repeatable read problem? Set the transaction isolation level to "repeatable read" repeatable read 

076df366e0d4488d9f087aba635263af.png

Demonstration of phantom reading problem:

bddd074a429642bc858db7ac0a4fb183.png 

Serializable tests

It can solve all problems, but it is inefficient. It is similar to Java's synchronized

Java uses synchronized to lock objects. MySQL uses serializable to lock the table. Transaction A starts the transaction and performs DML operations, but it is not submitted. At this time, transaction B starts the transaction and performs the select operation, but no data is queried because the tb_account table is occupied (locked) by transaction A at this time.

set session transaction isolation level serializable;

 3d470f16220b417aa5cfec7b7a5c0db8.png

 

 

Guess you like

Origin blog.csdn.net/shengshanlaolin_/article/details/128460801