MySql 事务Transaction

  • 事务 (transaction)的特性 ACID
    Atomicity

Transactions are atomic units of work that can be committed or rolled back.

Consistency

Isolation

支持并发操作,事务间互不干扰
MySQL:支持多事务并发工作的系统

Durability

Commit命令执行成功后,此次事务操作石锤

事务的生命周期管理

标准的事务控制语句(显式)

  • 开启事务
    begin / start transaction;

  • 提交事务
    commit

  • 回滚事务
    rollback

begin;
DML1
DML2
DML3
rollback; /  commit;

标准的事务语句
insert
update
delete
select

//case 1
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> use world
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> delete from city where id > 10;
Query OK, 4069 rows affected (0.06 sec)

mysql> rollback;
Query OK, 0 rows affected (0.05 sec)

// case 2
mysql> begin ;
Query OK, 0 rows affected (0.00 sec)

mysql> delete from city where id > 10;
Query OK, 4069 rows affected (0.06 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)


  • DDL语句无法回滚:删库 trancake

自动提交功能

mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            1 |
+--------------+
1 row in set (0.00 sec)

//重新导入world.sql
mysql> source /root/world.sql;
mysql> delete from city where id > 10;
Query OK, 4069 rows affected (0.09 sec)

mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
//失效!

autocommit = 1 时,没有加begin(没有显式开启事务)
执行结束后自动添加commit;
每条语句都是一个事务 --> 非交易类场景

交易类业务:
plan a: 将autocommit = 0
plan b: 每次发生事务时,显式声明begin, commit;

设置方法:
(1)临时生效

mysql> set global autocommit=0;
Query OK, 0 rows affected (0.00 sec)

(2) 永久生效
在my.cnf内添加:autocommit=0
重启mySQL:

[root@localhost ~]# /etc/init.d/mysqld restart
Shutting down MySQL.... SUCCESS! 
Starting MySQL. SUCCESS! 

隐式事务控制语句

  1. 设置了autocommit=1
  2. 执行了非DML语句(DDL,DCL),自动提交上面的语句
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> delete from city where id=1;
Query OK, 1 row affected (0.00 sec)

mysql> create table t1(id int);
Query OK, 0 rows affected (0.02 sec)

mysql> select * from city;
+----+----------------+-------------+---------------+------------+
| ID | Name           | CountryCode | District      | Population |
+----+----------------+-------------+---------------+------------+
|  2 | Qandahar       | AFG         | Qandahar      |     237500 |
|  3 | Herat          | AFG         | Herat         |     186800 |
|  4 | Mazar-e-Sharif | AFG         | Balkh         |     127800 |
|  5 | Amsterdam      | NLD         | Noord-Holland |     731200 |
|  6 | Rotterdam      | NLD         | Zuid-Holland  |     593321 |
|  7 | Haag           | NLD         | Zuid-Holland  |     440900 |
|  8 | Utrecht        | NLD         | Utrecht       |     234323 |
|  9 | Eindhoven      | NLD         | Noord-Brabant |     201843 |
| 10 | Tilburg        | NLD         | Noord-Brabant |     193238 |
+----+----------------+-------------+---------------+------------+
9 rows in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.01 sec)

mysql> select * from city;
+----+----------------+-------------+---------------+------------+
| ID | Name           | CountryCode | District      | Population |
+----+----------------+-------------+---------------+------------+
|  2 | Qandahar       | AFG         | Qandahar      |     237500 |
|  3 | Herat          | AFG         | Herat         |     186800 |
|  4 | Mazar-e-Sharif | AFG         | Balkh         |     127800 |
|  5 | Amsterdam      | NLD         | Noord-Holland |     731200 |
|  6 | Rotterdam      | NLD         | Zuid-Holland  |     593321 |
|  7 | Haag           | NLD         | Zuid-Holland  |     440900 |
|  8 | Utrecht        | NLD         | Utrecht       |     234323 |
|  9 | Eindhoven      | NLD         | Noord-Brabant |     201843 |
| 10 | Tilburg        | NLD         | Noord-Brabant |     193238 |
+----+----------------+-------------+---------------+------------+
9 rows in set (0.00 sec)
  • 隐式回滚:
    中途出事了,系统自动回滚

InnoDB 事务的ACID

名词认识

(1)重做日志
redo log : ib_logfile0~N 48M, 0~N轮询使用,记录数据页的变化
redo log buffer: redo 内存区域

(2)数据页存储位置
ibd : 存储数据行和索引
buffer pool: 缓冲区池,数据页和索引的缓冲

(3)LSN: 日志序列号
保证数据一致性
磁盘数据页,redo文件,buffer pool,redo buffer
MySQL每次启动,必须:磁盘数据页和redo log的LSN一致

(4)WAL:Write ahead log
日志优先写的方式实现持久化(日志写更加高效)
异步写

(5)脏页

(6)检查点
将脏页刷写到磁盘的动作

(7)TXID:事务号

(8)undo:ibdata1
存储了事务工作过程中的回滚信息

  • CSR = redo + undo

  • 一致性快照(SnapShot)

  • 隔离级别和锁机制

  1. transaction_isolation 事务隔离性
    1》 RU(Read Uncommited): 读未提交
    问题: 脏页读,不可重复读,幻读

2》RC(Read Commited): 读已提交
问题:不可重复读,幻读

3》RR(Repeatable Read): 可重复读 (默认)
问题:幻读
利用Undo的一致性快照读

4》SR(Serializable ): 可串行化
问题:串行化事务,但是不利于事务的并发

读指的是:page的读取(存储引擎的读(物理读),不是SQL层面的读)

脏读:别人的修改导致我的操作不正确
不可重复读,别人的修改导致我一个事务中同样操作不结果不一致
幻读:别人的修改,导致我的事务结果和预期不一致

RR 通过加入 GAP锁(间隙锁),next-lock避免幻读(基于辅助索引,在索引上加锁)

发布了316 篇原创文章 · 获赞 5 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_42347617/article/details/105207987