事务隔离实现并发控制:MySQL系列之十

一、并发访问控制

实现并发访问的控制技术是基于锁;

锁分为表级锁和行级锁,MyISAM存储引擎不支持行级锁;InnoDB支持表级锁和行级锁;

锁的分类有读锁和写锁,读锁也被称为共享锁,加读锁的时候其他的人可以读;写锁也称为独占锁或排它锁,一个写锁会阻塞其他读操作和写操作;

锁还分为隐式锁和显式锁,隐式锁由存储引擎自行管理,显式锁是用户手动添加锁;

锁策略:在锁粒度及数据安全性寻求的平衡机制。

显式锁的使用方法:LOCK TABLES tbl_name READ|WRITE

MariaDB [school]> LOCK TABLES students READ; #加读锁 MariaDB [school]> UNLOCK TABLES; #解锁

读锁:任何人都不可写

写锁:自己可以读写,但是其他人不可读写

FLUSH TABLES tb_name :关闭正在打开的表(清除查询缓存),通常在备份前加全局读锁

SELECT clause [FOR UPDATE | LOCK IN SHARE MODE] 查询时加写或读锁

二、事务Transactions

​ 一组原子性的SQL语句,或一个独立工作单元

1、事务遵循ACID原则:

A:atomicity原子性;整个事务中的所有操作要么全部成功执行,要么全部失败后回滚

C:consistency一致性;数据库总是从一个一致性状态转换为另一个一致性状态

I:Isolation隔离性;一个事务所做出的操作在提交之前,是不能为其它事务所见;隔离有多种隔离级别,实现并发

D:durability持久性;一旦事务提交,其所做的修改会永久保存于数据库中

2、事务的生命周期

显式事务:明确的规定事务的开始

隐式事务:默认为隐式事务,每执行完一句语句后直接提交

autocommit = {OFF|ON} 开启或关闭自动提交,建议使用显式请求和提交事务,而不要使用“自动提交”功能

启动事务:START TRANSACTION;

插入标签:ROLLBACK TO ##;

撤销回指定标签:ROLLBACK TO ##;

全部撤销:ROLLBACK;

提交事务:COMMIT;

删除标签:RELEASE SAVEPOINT;

MariaDB [school]> START TRANSACTION; #明确指明启动一个事务 MariaDB [school]> INSERT students(StuID,Name,Age,Gender) VALUES (26,'Tom',22,'M'); #添加一条记录 MariaDB [school]> SAVEPOINT sp26; #插入一个标签 MariaDB [school]> INSERT students(StuID,Name,Age,Gender) VALUES (27,'Maria',12,'F'); #再加入一条记录 MariaDB [school]> SELECT * FROM students WHERE stuid IN (26,27); #查看一下,可以看到刚刚插入的数据 +-------+-------+-----+--------+---------+-----------+ | StuID | Name | Age | Gender | ClassID | TeacherID | +-------+-------+-----+--------+---------+-----------+ | 26 | Tom | 22 | M | NULL | NULL | | 27 | Maria | 12 | F | NULL | NULL | +-------+-------+-----+--------+---------+-----------+ MariaDB [school]> ROLLBACK TO sp26; #撤销到sp26标签之前的状态 MariaDB [school]> SELECT * FROM students WHERE stuid IN (26,27); #查看一下,刚刚maria的信息被撤回了 +-------+------+-----+--------+---------+-----------+ | StuID | Name | Age | Gender | ClassID | TeacherID | +-------+------+-----+--------+---------+-----------+ | 26 | Tom | 22 | M | NULL | NULL | +-------+------+-----+--------+---------+-----------+ MariaDB [school]> COMMIT; #提交事务 MariaDB [school]> SELECT * FROM students WHERE stuid IN (26,27); #最终的数据 +-------+------+-----+--------+---------+-----------+ | StuID | Name | Age | Gender | ClassID | TeacherID | +-------+------+-----+--------+---------+-----------+ | 26 | Tom | 22 | M | NULL | NULL | +-------+------+-----+--------+---------+-----------+ 3、事务的隔离级别

READ UNCOMMITTED 其他事务可以看到未提交的脏数据,产生脏读

READ COMMITTED 提交后其他事务可以看到修改后的数据,每次读取的数据可能不一致,不可重复读

REPEATABLE READ 可重复读,每次看到的数据都一致,数据被修改后看不到最新数据,会产生幻读(默认设置)

SETIALIZABILE 未提交的读事务阻塞修改事务,串行执行,并发性差

MVCC: 多版本并发控制,和事务级别相关

修改事务隔离级别:服务器变量tx_isolation指定,默认为REPEATABLE-READ,可在GLOBAL和SESSION级进行设置

tx_isolation

Description: The transaction isolation level. See also SET TRANSACTION ISOLATION LEVEL.

Commandline: --transaction-isolation=name

Scope: Global, Session

Dynamic: Yes

Type: enumeration

Default Value: REPEATABLE-READ

Valid Values: READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE

MariaDB [school]> SELECT @@tx_isolation; #默认为可重复读级别 +-----------------+ | @@tx_isolation | +-----------------+ | REPEATABLE-READ | +-----------------+ MariaDB [school]> SET tx_isolation='READ-UNCOMMITTED'; MariaDB [school]> set tx_isolation='READ-COMMITTED'; MariaDB [school]> set tx_isolation='REPEATABLE-READ'; MariaDB [school]> set tx_isolation='SERIALIZABLE'; 4、死锁

​ 两个或多个事务在同一资源相互占用,并请求锁定对方占用的资源的状态会发生死锁

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgyjpj.html