MySQL好好学三(事务和锁)

MySQL好好学三(事务和锁)

大纲

  • MySQL事务机制

  • MySQL锁机制

MySQL事务

        当多个用户访问同一数据时,一个用户在更改数据的过程中可能有其它用户同时发起更改请求,为保证数据的一致性状态,MySQL 引入了事务。

1、事务及其特性

        数据库的事务(Transaction)是一种机制、一个操作序列,包含了一组数据库操作命令。事务把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么都执行,要么都不执行,因此事务是一个不可分割的工作逻辑单元。

        事务具有 4 个特性,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability),这 4 个特性通常简称为 ACID。

-- 原子性
事务是一个完整的操作。事务的各元素是不可分的(原子的)。事务中的所有元素必须作为一个整体提交或回滚。如果事务中的任何元素失败,则整个事务将失败。
-- 一致性
事务执行前后,数据库数据的一致性状态不变。
-- 隔离性
对数据进行修改的所有并发事务是彼此隔离的,相互之间互不影响。
-- 持久性
一个事务成功完成之后,它对数据库所作的改变是永久性的,一旦事务被提交,事务对数据所做的任何变动都会被永久地保留在数据库中。
2、事务的语法和配置

        MySQL 提供了多种存储引擎来支持事务。支持事务的存储引擎有 InnoDB 和 BDB,其中,InnoDB 存储引擎事务主要通过 UNDO 日志和 REDO 日志实现,MyISAM 存储引擎不支持事务。

 为了维护 MySQL 服务器,经常需要在 MySQL 数据库中进行日志操作:

  • UNDO 日志:复制事务执行前的数据,用于在事务发生异常时回滚数据。
  • REDO 日志:记录在事务执行中,每条对数据进行更新的操作,当事务提交时,该内容将被刷新到磁盘。
-- 开始事务
BEGIN; 或者  START TRANSACTION
-- 提交事务
COMMIT;
-- 回滚事务
ROLLBACK;

-- 配置mysql自动提交事务(开启或者关闭)
mysql> SHOW VARIABLES LIKE 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set, 1 warning (0.04 sec) 
在 MySQL 中,可以使用 SET autocommit 语句设置事务的自动提交模式,语法格式如下:
SET autocommit = 0|1|ON|OFF; 
对取值的说明:
值为 0 和值为 OFF:关闭事务自动提交。如果关闭自动提交,用户将会一直处于某个事务中,只有提交或回滚后才会结束当前事务,重新开始一个新事务。
值为 1 和值为 ON:开启事务自动提交。如果开启自动提交,则每执行一条 SQL 语句,事务都会提交一次。
3、事务隔离级别

        当有两个或两个以上的事务同时执行、提交事务时,可能会引发并发事务问题,并发事务常见的问题有:

  • 脏读:一个事务读取了另一个事务还没提交的数据;

  • 不可重复读:一个事务先后读取同一条记录,但两次读取的数据不同,这种称为不可重复读;

  • 幻读:一个事务按照条件前后查询数据时,对应的数据行数不一致,好像出现了“幻影”。

        为了解决事务并发问题,我们设置事务的隔离级别,不同的隔离级别可以解决不同的事务并发问题,如下表:

隔离级别脏读不可重复读幻读
Read uncommitted不可解决不可解决不可解决
Read committed可解决不可解决不可解决
Repeatable Read(默认)可解决可解决不可解决
Serializable可解决可解决可解决
-- 查看会话(当前)全局隔级别
SELECT @@session.tx_isolation;
SELECT @@tx_isolation;
-- 查看全局隔级别
SELECT @@global.tx_isolation;
-- 设置当前会话 or 全局隔离级别语法
语法:
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ
COMMITTED | REPEATABLE READ | SERIALIZABLE} 
示例:
set session transaction isolation level REPEATABLE READ;

MySQL锁机制

        Mysql为了解决并发、数据安全的问题,使用了锁机制。

1、锁的分类
  • 模式分类:(乐观锁+悲观锁)
-- 乐观锁概念
数据提交更新的时候才会去检测。
-- 实现
乐观锁是基本版本号机制实现的,数据表中增加一个 version 字段,读取数据时将 version 一起读出。数据每更新一次,version 字段值 + 1。当修改需要提交时,将读取时的版本号与数据库当前版本号做比较,如果一致,说明在此期间无人修改这条记录,不一致则说明已经被修改了,提交失败
-- 适用场景
读多写少

-- 悲观锁
悲观锁通过共享锁和排他锁实现,适用于并发量不大,写操作多,读操作少的场景
  • 粒度分类:(全局锁、表级锁、页级锁、行锁)
-- 全局锁
锁数据库,用于全库逻辑备份。
-- 全局锁,整个数据库处于只读状态,其他操作均阻塞
 FLUSH TABLES WITH READ LOCK
-- 释放全局锁
 UNLOCK TABLES

-- 表级锁
锁整张表,
加锁:LOCK TABLES 表名 READ|WRITE
解锁:UNLOCK TABLES

-- 行锁
锁表的某一行记录。
  • 属性分类:(共享锁S、排它锁X)

  • 状态分类:(意向共享锁IS、意向排它锁IX)

  • 算法分类:(间隙锁、临键锁、记录锁)

end
  • 作者:旭仔(联系作者)
  • 发表时间:2024-03-06 20:22
  • 版权声明:自由转载-非商用-非衍生-保持署名
  • 转载声明:如果是转载栈主转载的文章,请附上原文链接
  • 公众号转载:请在文末添加作者公众号二维码(公众号二维码见右边,欢迎关注)
  • 评论