目录
参考:
1. 事务
1.1. 概述
-
定义
- 为单个工作单元而执行的一系列操作。如查询、修改数据、修改数据定义。
- 如果不显式定义事务的边界,每条语句作为一个事务,执行完每个语句之后自动提交;
-
语法
BEGIN TRAN
INSERT INTO b(t1) VALUES(1)
INSERT INTO b(t1) VALUES(2)
COMMIT TRAN
-- 创建保存点identifier
SAVEPOINT identifier
-- 回滚到 指定保存点
ROLLBACK [WORK] TO [SAVEPOINT] identifier
-- 释放 指定保存点
RELEASE SAVEPOINT identifier
-- 示例:
START TRANSACTION
[transaction_characteristic [, transaction_characteristic] ...]
transaction_characteristic: {
WITH CONSISTENT SNAPSHOT
| READ WRITE
| READ ONLY
}
BEGIN [WORK]
COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
SET autocommit = {0 | 1}
参考:
1.2. 事务与死锁
- 事务与锁表
--查询这个超过10秒未提交事务的详细信息:
SELECT t.trx_mysql_thread_id
,t.trx_state
,t.trx_tables_in_use
,t.trx_tables_locked
,t.trx_query
,t.trx_rows_locked
,t.trx_rows_modified
,t.trx_lock_structs
,t.trx_started
,t.trx_isolation_level
,p.time
,p.user
,p.host
,p.db
,p.command
FROM information_schema.innodb_trx t
INNER JOIN information_schema.processlist p
ON t.trx_mysql_thread_id = p.id
WHERE t.trx_state = 'RUNNING'
AND p.time > 10
AND p.command = 'Sleep'\G
select * from information_schema.innodb_trx where trx_query is null;
1.3. ACID特性
2. 锁
2.1. 概述
- 事务中的锁
- 通过锁来实现事物的隔离;
- 事务获取锁,用于保护数据,防止其他事物对数据进行冲突的或不兼容的访问;
2.2. 分类
- 概述: mysql中行级锁中的共享锁与排他锁
- 共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。
- 排他锁又称为写锁,简称X锁,顾名思义,排他锁就是不能与其他所并存,如一个事务获取了一个数据行的排他锁,
- 其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他锁的事务是可以对数据就行读取和修改。
参考:
2.2.1. 排他锁
2.2.2. 共享锁
2.2.3. 死锁
- “死锁 (Dead Lock)”的一些注意事项:
- 如果两个事务没有设置死锁优先级,且两个事务进行的工作量也差不多一样时,任何一个事务都有可能被终止。
- 解除死锁要付出一定的系统开销,因为这个过程会涉及撤销已经执行过的处理。
- 事务处理的时间时间越长,持有锁的时间就越长,死锁的可能性也就越大,应该尽可能保持事务简短,把逻辑上可以不属于同一个工作单元的操作移到事务以外。
- 事务A和事务B以相反顺序访问资源,所以发生了死锁。如果两个事务按同样的顺序来访问资源,则不会发生这种类型的死锁。在不改变程序的逻辑情况下,可以通过交换顺序来解决死锁的问题。
3. 阻塞
4. 事务隔离级别
4.1. 写
4.2. 读
- 总结
- 脏读:读取未提交的更改。
- 不可重复读: 在一个事务开启过程中,当前事务读取到了另一事务提交的修改。
- 读操作不会在事务持续期间内保留共享锁,其他事务可以在两个读操作之间更改数据资源,读操作因而可能每次得到不同的取值。
-
- 幻读:在一个事务开启过程中,读取到另一个事务提交导致的数据条目的新增或删除。
- 范围锁:读操作锁定满足查询搜索条件范围的锁
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wl6qu5A0-1626938799273)(https://cdn.jsdelivr.net/gh/VK-Link/Markdown@master/imgs_for_blogs/20210427191139.png)]
4.2.1. 未提交读(READ UNCOMMITTED)
- RU 概述
- 读操作可以读取未提交的修改(也称为脏读)。
- 读操作不会妨碍写操作请求排他锁,其他事务正在进行读操作时,写操作可以同时对这些数据进行修改。
- 事务A进行了多次修改,事务B在不同阶段进行查询时可能会有不同的结果。
4.2.2. 已提交读 (READ COMMITTED)
“已提交读 (READ UNCOMMITTED)”隔离级别的含义:
- 必须获得共享锁才能进行读操作,其他事务如果对该资源持有排他锁,则共享锁必须等待排他锁释放。
- 读操作不能读取未提交的修改,读操作读取到的数据是提交过的修改。
- 读操作不会在事务持续期间内保留共享锁,其他事务可以在两个读操作之间更改数据资源,读操作因而可能每次得到不同的取值。这种现象称为“不可重复读”
4.2.3. 可重复读 (REPEATABLE READ)
“可重复读 (REPEATABLE READ)”隔离级别的含义:
- 必须获得共享锁才能进行读操作,获得的共享锁将一直保持直到事务完成之止。
- 在获得共享锁的事务完成之前,没有其他事务能够获得排他锁修改这一数据资源,这样可以保证实现可重复的读取。
- 两个事务在第一次读操作之后都将保留它们获得的共享锁,所以任何一个事务都不能获得为了更新数据而需要的排他锁,这种情况将会导致死锁(deadlock),不过却避免了更新冲突。
4.2.4. 可序列化(SERIALIZABLE)
“可序列化(SERIALIZABLE)”隔离级别的含义:
- 必须获得共享锁才能进行读操作,获得的共享锁将一直保持直到事务完成之止。
- 在获得共享锁的事务完成之前,没有其他事务能够获得排他锁修改这一数据资源,且当其他事务增加能够满足当前事务的读操作的查询搜索条件的新行时,其他事务将会被阻塞,直到当前事务完成然后释放共享锁,其他事务才能获得排他锁进行插入操作.
- 事务中的读操作在任何情况下读取到的数据是一致的,不会出现幻影行(幻读)。
- 范围锁:读操作锁定满足查询搜索条件范围的锁
参考:
- 全面解析-SQL事务+隔离级别+阻塞+死锁 //有举例;