笑看天下无敌手 发表于 2024-8-29 10:43:56

mysql查线上数据注意数据库的隔离级别

数据库的隔离级别定义了一个事务大概对其他并发事务的可见性,以及它们大概对数据库的影响。隔离级别的选择影响着并发性能和数据的一致性,不同的隔离级别能够防止不同水平的并发问题,如脏读(Dirty Reads)、不可重复读(Nonrepeatable Reads)和幻读(Phantom Reads)。
SQL标准定义了四种隔离级别:
1. 读未提交 (Read Uncommitted)

这是最低的隔离级别,事务可以读取到其他未提交事务的更改。这意味着大概会出现脏读,即一个事务大概读到另一个事务未提交的数据。
例子:
事务A修改了一行数据但还未提交,此时事务B在此隔离级别下可以看到这个修改。
-- 事务A
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;

-- 事务B
BEGIN;
SELECT balance FROM accounts WHERE id = 1; -- 可以看到事务A未提交的更改

2. 读提交 (Read Committed)

在这个隔离级别下,一个事务只能读取到其他事务已提交的更改。这避免了脏读,但仍然大概出现不可重复读,即在同一事务中两次相同的查询大概返回不同的结果。
例子:
-- 事务A
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT;

-- 事务B
BEGIN;
SELECT balance FROM accounts WHERE id = 1; -- 第一次查询
-- 事务A提交更改
SELECT balance FROM accounts WHERE id = 1; -- 第二次查询,可能会看到不同的结果
COMMIT;

3. 可重复读 (Repeatable Read)

在这个隔离级别下,保证在同一事务中多次读取相同的数据会看到相同的结果,即不可重复读现象被防止了。但是,大概会出现幻读,即在同一事务中读取到其他事务新插入的行。
例子:
-- 事务A
BEGIN;
SELECT * FROM accounts WHERE balance > 1000; -- 第一次查询

-- 事务B
BEGIN;
INSERT INTO accounts (id, balance) VALUES (3, 2000);
COMMIT;

-- 事务A
SELECT * FROM accounts WHERE balance > 1000; -- 第二次查询可能包含了事务B新插入的行
COMMIT;

4. 串行化 (Serializable)

这是最高的隔离级别,它完全隔离了事务,使它们不能并行执行。任何并发的环境都会被阻止,从而避免脏读、不可重复读和幻读。但这也大大低落了并发性能。
例子:
-- 事务A
BEGIN;
SELECT * FROM accounts WHERE balance > 1000; -- 对结果集加锁

-- 事务B
BEGIN;
-- 尝试插入新行或更新满足上述SELECT条件的行将会被阻塞,直到事务A提交或回滚
INSERT INTO accounts (id, balance) VALUES (3, 2000); -- 被阻塞

在选择隔离级别时,通常需要在并发性能和数据一致性之间做出衡量。假如可担当一定水平的不一致性以获得更高的并发性能,可以选择较低的隔离级别(如读未提交或读提交)。假如数据一致性非常关键,大概需要选择较高的隔离级别(如可重复读或串行化)。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: mysql查线上数据注意数据库的隔离级别