事务的隔离级别及mysql对应操作

时间:2024-11-07 08:06:07
/*
本次高并发解决之道
1,更改事务隔离级别为 read uncommitted读未提交 2,查询前设定延迟,延迟时间为随机 50-500 微秒 3,修改数据前将 超范围作为 限定修改条件 事务是作为单个逻辑工作单元执行的一系列操作.可以是一条SQL语句也可以是多条SQL语句.一个支持事务 Transaction的数据库系统,必需要具有这四种特性,以保证保证数据的正确性 事务的隔离级别
隔离级别与并发性是互为矛盾的:隔离程度越高,数据库的并发性越差;隔离程度越低,数据库的并发性越好。 隔离级别 脏读 不可重复读 幻读
读未提交(Read uncommitted) 可能 可能 可能
读已提交(Read committed) 不可能 可能 可能
可重复读(Repeatable read) 不可能 不可能 可能
可串行化(Serializable ) 不可能 不可能 不可能 脏读(Dirty Read)
当事务读取还未被提交的数据时,就会发生这种事件。举例来说:Transaction1修改了一行数据,然后Transaction2在 Transaction1还未提交修改操作之前读取了被修改过的数据。如果Transaction1回滚了修改操作,那么Transaction2读取的数据就可以看作是从未存在过的。 不可重复读(NonRepeatable Read)
一个事务范围内两个相同的查询却返回了不同数据。这是由于查询时系统中其他事务修改数据后提交而引起的。比如事务Transactio1读取某一数据,事务Transaction2读取并修改了该数据后提交,Transaction1为了对读取值进行检验而再次读取该数据,便得到了不同的结果。 幻读(Phantom Read)
如果符合搜索条件的一行数据在后面的读取操作中出现,但该行数据却不属于最初的数据,就会发生这种事件。举例来说Transactio1读取满足某种搜索条件的一些行,然后Transaction2插入了符合Transaction1的搜索条件的一个新行。如果Transaction1重新执行相同查询及条件,就会得到不同的行 Read Uncommitted (Oracle不支持)
最低等级的事务隔离,仅仅保证了读取过程中不会读取到非法数据。上诉4种不确定情况均有可能发生。
与READ COMMITTED 隔离级相反它允许读取已经被其它用户修改但尚未提交确定的数据限制级别最小,脏读在这个隔离级别下是非Consistent Reads的 Read Committed (SQL Server, Oracle默认)
大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了"脏读取",该级别适用于大多数系统. Repeatable Read (MySQL默认,Oracle不支持)
保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但是带来了更多的性能损失。 Serializable (Oracle中Read only和这个很相似,唯一区别是Read only事务不允许修改,因此不会遇到ORA-08177错误)
最高等级的事务隔离,上面3种不确定情况都将被规避。这个级别将模拟事务的串行执行。-- updated 2009-09-15 from《Expert Oracle Database Architecture》P239
这是最大的限制,和X锁类似,不允许其他事务进行任何写访问。如非必要,不要使用这个选项。在事务的开始使用这个命令即可,该隔离级别一直对该SQL Server连接(不是本事务)有效,直到下一次使用本命令设置了新的隔离级别为止。
*/ -- 以下4种隔离级别都会以创建事务的测试步骤来进行测试 -- 开始事务:
start transaction
-- 设置会话事务级别:
set session transaction isolation level ( read uncommitted / read committed / repeatable read / serializable )
-- 提交事务:
commit
-- 回滚事务:
rollback SET TRANSACTION ISOLATION LEVEL -- 只能在开启事务前执行
SET SESSION TRANSACTION ISOLATION LEVEL -- 可以在开启事务后执行 -- 脏读(Dirty Read)
-- 用户1操作
START TRANSACTION;
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
UPDATE t1 SET test_str = '测试内容2' WHERE id = 1;
-- 用户2操作
START TRANSACTION;
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM t1 WHERE id = 1;
-- 用户1操作
ROLLBACK;
-- 用户2操作
SELECT * FROM t1 WHERE id = 1;
ROLLBACK; -- 不可重复读(NonRepeatable Read)
-- 用户1操作
START TRANSACTION;
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM t1 WHERE id = 1;
-- 用户2操作
START TRANSACTION;
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
UPDATE t1 SET test_str = '修改后的测试内容' WHERE id = 1;
COMMIT;
-- 用户1操作
SELECT * FROM t1 WHERE id = 1;
ROLLBACK; -- 幻读(Phantom Read)
-- 用户1操作
START TRANSACTION;
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM t1;
-- 用户2操作
START TRANSACTION;
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
INSERT INTO `test`.`t1` (`storage_num`, `test_str`) VALUES ('', '测试内容1');
-- 用户1操作
SELECT * FROM t1;
ROLLBACK;
-- 用户2操作
ROLLBACK;