首先说明下,如果我们只谈MySQL事务 操作,而不谈MySQL的引擎,那属于无知和耍流氓,接下来我们先来谈谈MySQL引擎。
MySQL常见引擎
- InnoDB存储引擎
InnoDB是事务型数据库的首选引擎,支持事务安全表(ACID),支持行锁定和外键,同时InnoDB存储引擎是MySQL的默认引擎 - MyISAM存储引擎
MyISAM基于ISAM存储引擎,并对其进行扩展。它是在Web、数据仓储和其他应用环境下最常使用的存储引擎之一。MyISAM拥有较高的插入、查询速度,但不支持事物操作。 - MEMORY存储引擎
MEMORY存储引擎将表中的数据存储到内存中,未查询和引用其他表数据提供快速访问,但是不支持事务操作。
MySQL常用引擎的具体对比
结论:通过上图对比得知,事务操作只存在于InnoDB存储引擎下,其他数据库引擎是不支持MySQL的事务操作的。
OK,基于以上结论我们接着聊事务。
事务操作只存在于InnoDB存储引擎下
接下来正式进入MySQL事务
- 事务定义
英文全称:Transaction
事务:一个最小的不可再分的工作单元;通常一个事务对应一个完整的业务(例如银行账户转账业务,该业务就是一个最小的工作单元) - InnoDB存储引擎下,事务的应用场景?
A. InnoDB存储引擎下,DML(insert、update、delete)增删改操作会自动触发事务操作;
B. 工作中常见应用场景还包括:积分兑换、银行转账等场景
- 事务的四大特性
原子性(A):事务是最小单位,不可再分
一致性 (C):事务要求所有的DML语句操作的时候,必须保证同时成功或者同时失败
隔离性(I):事务A和事务B之间具有隔离性
持久性(D):是事务的保证,事务终结的标志(内存的数据持久到硬盘文件中)
- 常见事物的术语包括:
开启事务:Start Transaction
事务结束:End Transaction
提交事务:Commit Transaction
回滚事务:Rollback Transaction
- 事务操作命令包括:
事务开启 :begin 或者 start transaction
事务提交 :commit
事务回滚 :rollback
- 事物开启的标志
InnoDB引擎下,任何一条DML语句(insert、update、delete)执行,标志事务的开启
- 事务结束的标志
提交:成功的结束,将所有的DML语句操作历史记录和底层硬盘数据来一次同步
回滚:失败的结束,将所有的DML语句操作历史记录全部清空
- 事物与数据库底层数据
在事物进行过程中,未结束之前,DML语句是不会更改底层数据,只是将历史操作记录一下,在内存中完成记录。只有在事物结束的时候,而且是成功的结束的时候,才会修改底层硬盘文件中的数据
- 事物的隔离特性(今天重点聊)
事物A和事物B之间具有一定的隔离性,即:不同的事务操作之间具有隔离性;
InnoDB引擎下,MySQL常见的事务隔离级别
隔离性有隔离级别(4个)
读未提交:read uncommitted
读已提交:read committed
可重复读:repeatable read
串行化:serializable
1、 read uncommitted
- 事物A和事物B,事物A未提交的数据,事物B可以读取到
- 这里读取到的数据叫做“脏数据”
- 这种隔离级别最低,这种级别一般是在理论上存在,数据库隔离级别一般都高于该级别
2、read committed
- 事物A和事物B,事物A提交的数据,事物B才能读取到
- 这种隔离级别高于读未提交
- 换句话说,对方事物提交之后的数据,我当前事物才能读取到
- 这种级别可以避免“脏数据”
- 这种隔离级别会导致“不可重复读取”
- Oracle默认隔离级别
3、repeatable read
- 事务A和事务B,事务A提交之后的数据,事务B读取不到
- 事务B是可重复读取数据
- 这种隔离级别高于读已提交
- 换句话说,对方提交之后的数据,我还是读取不到
- 这种隔离级别可以避免“不可重复读取”,达到可重复读取
- 比如1点和2点读到数据是同一个
- MySQL默认级别
- 虽然可以达到可重复读取,但是会导致“幻像读”
4、serializable
- 事务A和事务B,事务A在操作数据库时,事务B只能排队等待
- 这种隔离级别很少使用,吞吐量太低,用户体验差
- 这种级别可以避免“幻像读”,每一次读取的都是数据库中真实存在数据,事务A与事务B串行,而不并发
扩展:
设置隔离级别
方式一:
可以在my.ini文件中使用transaction-isolation选项来设置服务器的缺省事务隔离级别。
该选项值参考:
– READ-UNCOMMITTED
– READ-COMMITTED
– REPEATABLE-READ(默认隔离级别)
– SERIALIZABLE
my.ini文件中:
[mysqld]
transaction-isolation = READ-COMMITTED
方式二:
通过命令动态设置隔离级别
隔离级别也可以在运行的服务器中动态设置,应使用SET TRANSACTION ISOLATION LEVEL语句。
其语法格式参考:
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL <isolation-level>(隔离级别)
其中的隔离级别可以是:
– READ UNCOMMITTED
– READ COMMITTED
– REPEATABLE READ
– SERIALIZABLE
• 例如: SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
设置MySQL事务隔离级别的作用范围
• 事务隔离级别的作用范围分为两种:
– 全局级:对所有的会话有效
– 会话级:只对当前的会话有效
• 例如,设置会话级隔离级别为READ COMMITTED :
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
或:
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
• 设置全局级隔离级别为READ COMMITTED :
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;