Mysql中的事务和锁

Mysql事务和锁

这里主要讲的是Mysql InnoDB引擎相关事务和锁。Mysql事务主要和上诉数据库理论中类似,有所不同的是在事务隔离级别的Repeatable Read(可重复读)、和锁有着不同的实现。

mysql的隔离级别
  • Read Uncommitted(读取未提交内容)
    在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。
    读取未提交的数据,则会发生赃读
  • Read Committed(读取提交内容)
    一个事务只能看见已经提交事务所做的改变。这是大多数数据库系统的默认隔离级别,但非MySql
    一个事务多次读取的过程中,另一个事务可能对同一条数据做修改并提交,导致前一个事务多次读取到的数据不一致,则会发生不可重复读
  • Repeatable Read(可重读)
    它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。这是MySql的默认隔离级别
    但,此级别依然会发生幻读
  • Serializable(可串行化)
    它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题

创建一个表格

隔离级别 读数据一致性 赃读 不可重复读 幻读
Read Uncommitted 最低级别,只能保证不读取物理上损坏的数据
Read Committed 语句级 ×
Repeatable Read 事务及 ×
Serializable 最高级别,事务级 × × ×

低级别的隔离一般支持更高的并发处理,并拥有更低的系统消耗。高级别的隔离可靠性较高,但系统性能消耗较大。

隔离级别测试

创建数据库

CREATE DATABASE IF NOT EXISTS txdemo DEFAULT CHARSET utf8 COLLATE utf8_general_ci;

创建测试表

CREATE TABLE `user` (
    `id`    BIGINT NOT NULL AUTO_INCREMENT,
    `name`  VARCHAR(32) NOT NULL DEFAULT '',
    `age`   INT(16) NOT NULL DEFAULT '30',
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

插入测试数据

INSERT INTO user (name, age) VALUES ('manerfan', 30), ('Abel', 28), ('Cherry', 42);

Read Uncommitted
Mysql中的事务和锁_第1张图片
Step 1: 设置A的隔离级别为Read Uncommitted,开启事务并读取数据
Step 2: B开启事务,修改数据,但不提交
Step 3: A读取数据,发现数据已变
Step 4: B回滚,但不提交
Step 5: A读取数据,发现数据恢复

A事务中可以读取到B事务未修改的数据,发生赃读

Read Committed
Mysql中的事务和锁_第2张图片
Step 1: 设置A的隔离级别为Read Committed,开启事务并读取数据
Step 2: B开启事务,修改数据,但不提交
Step 3: A读取数据,发现数据未变
Step 4: B提交事务
Step 5: A读取数据,发现数据改变

已提交读隔离级别解决了脏读的问题,但是出现了不可重复读的问题,即事务A在两次查询的数据不一致,因为在两次查询之间事务B更新了一条数据。

Repeatable Read
Mysql中的事务和锁_第3张图片
Step 1: 设置A的隔离级别为Repeatable Read,开启事务并读取数据
Step 2: B开启事务,修改数据,但不提交
Step 3: A读取数据,发现数据未变
Step 4: B提交事务
Step 5: A读取数据,发现数据依然未变,解决了不可重复读
Step 6: B插入新数据,并提交
Step 7: A读取数据,发现数据还是未变,出现幻读
Step 8: A提交事务,再次读取数据,发现数据改变

Repeatable Read隔离级别只允许读取已提交记录,而且在一个事务两次读取一个记录期间,其他事务的更新不会影响该事务。但该事务不要求与其他事务可串行化,可能会发生幻读。

乐观锁与悲观锁

乐观锁(Optimistic Lock),是指操作数据库时(更新操作),总是认为这次的操作不会导致冲突,不到万不得已不去拿锁,在更新时采取判断是否冲突,适用于读操作远多于更新操作的情况。
乐观锁并没有被数据库实现,需要自行实现,通常的实现方式为在表中增加版本version字段,更新时判断库中version与取出时的version值是否相等,若相等则执行更新并将version加1,若不相等则说明数据被其他线程(进程)修改,放弃修改。

悲观锁(Pessimistic Lock),是指操作数据库时(更新操作),总是认为这次的操作会导致冲突,每次都要通过获取锁才能进行数据操作,因此要先确保获取锁成功再进行业务操作。
悲观锁需要数据库自身提供支持。

总结

今天就分享到这里,主要是回顾和学习了事务相关的种种概念和知识点,感觉还是很有收获的,很多不懂的地方现在也解释的通了。贴上参考学习的链接:
CSDN链接: https://blog.csdn.net/Sugar_Rainbow/article/details/77926216
百度文库链接: https://wenku.baidu.com/view/628ea6293d1ec5da50e2524de518964bce84d255.html
博客园链接:https://www.cnblogs.com/wangkaihua/archive/2019/01/03/10217490.html

你可能感兴趣的:(Mysql中的事务和锁)