首页 开云体育 关于开云 开云资讯 开云滚球 开云盘口 2026世界杯 开云app下载
  • 首页
  • 开云体育
  • 关于开云
  • 开云资讯
  • 开云滚球
  • 开云盘口
  • 2026世界杯
  • 开云app下载
  • 关于开云

    你的位置:开云体育官方网站 - KAIYUN > 关于开云 > 开云体育官方网站 事务破损级别

    开云体育官方网站 事务破损级别

    发布日期:2026-03-08 11:18    点击次数:198

    开云体育官方网站 事务破损级别

    在mysql中,如若有深广用户同期拜谒修改并吞条数据,将会产生数据一致性的问题,本文来沟通mysql是如何处理这个问题的。

    场景预设CREATE DATABASE IF NOT EXISTS `isolation_lab`;

    USE `isolation_lab`;

    {jz:field.toptypename/}

    --

    DROP TABLE IF EXISTS `account`; CREATE TABLE `account` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `name` VARCHAR(50) NOT NULL, `balance` DECIMAL(10,2) NOT NULL DEFAULT 0.00, `version` INT DEFAULT 0 ) ENGINE=InnoDB;

    --

    INSERT INTO `account` (`name`, `balance`) VALUES ('张三', 1000.00), ('李四', 500.00), ('王五', 2000.00);

    -- #MySQL #SQL #每天一个常识点

    DROP TABLE IF EXISTS `transaction_log`; CREATE TABLE `transaction_log` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `from_account` VARCHAR(50), `to_account` VARCHAR(50), `amount` DECIMAL(10,2), `create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB;

    并发事务的三大问题脏读脏读 等于读取到了其他事务尚未提交的数据,底下来创建一个脏读的情况 脏数据 是指 未提交的、不踏实的临时数据 。

    --

    -- 需要两个寂静的 MySQL 客户端会话(会话 A 会通话 B)

    --

    --

    SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; START TRANSACTION;

    --

    UPDATE account SET balance = balance - 200 WHERE name = '张三';

    --

    --

    SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; START TRANSACTION;

    --

    SELECT balance FROM account WHERE name = '张三'; -- 效果:800.00(但会话 A 可能随时回滚!)

    --

    --

    ROLLBACK;

    --

    --

    SELECT balance FROM account WHERE name = '张三'; -- 效果:1000.00(刚才读到的800是"脏数据")

    这种情况会导致会话 B 很可能凭证读取到的800来作念出一些有贪图,然而会话 A 又回滚数据了,导致会话 B 的后续有贪图(针对800)是关于实践的1000这个数据作念的。

    或者会话 A 插入一条新的数据,但未提交,会话 B 凭证这条新数据作念了操作,会话 A 回滚,导致业务逻辑十足乖张。

    不能重读不能重读 等于并吞事务中屡次读取并吞数据,效果 不一致 --

    UPDATE account SET balance = 1000.00 WHERE name = '张三';

    --

    SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; START TRANSACTION;

    --

    SELECT balance FROM account WHERE name = '张三'; -- 效果:1000.00

    --

    --

    START TRANSACTION; UPDATE account SET balance = 800.00 WHERE name = '张三'; COMMIT;

    --

    --

    SELECT balance FROM account WHERE name = '张三'; -- 效果:800.00(与第一次读取不一致!)

    --

    --

    COMMIT;

    有东谈主可能会很猜忌,并吞事务中屡次读取并吞数据,效果不一致 ,是不能重读,那 脏读 不相通是在一个事务中可能读到不同的数据吗?

    其实质分手是: 脏读 是读取了 事务未提交 的数据, 不能重读 是读取了 其他事务还是提交的数据 2. 脏读 的数据是临时的,可能被回滚,从未的确见效, 不能重读 的数据是真实的幻读幻读 是并吞事务中屡次查询,复返的 行数 不一致

    --

    --

    SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; --

    START TRANSACTION;

    --

    SELECT COUNT(*) FROM account WHERE balance > 600; -- 效果:2(张三1000,王五2000)

    --

    --

    START TRANSACTION; INSERT INTO account (name, balance) VALUES ('赵六', 700.00); COMMIT;

    --

    --

    SELECT COUNT(*) FROM account WHERE balance > 600; -- 效果:2(在 REPEATABLE READ 下看不到新插入的赵六)

    --

    UPDATE account SET version = version +

    SELECT ROW_COUNT; -- 影响了3行!包括赵六!

    --

    SELECT COUNT(*) FROM account WHERE balance > 600; --

    COMMIT;

    这个效果相配的神奇,kaiyun sports那么到底发生了什么,会产生这种情况?

    因为在 可重叠读 这个事务破损级别中,具有 快照读 和 现时读 两种机制:

    第一次使用 select 进行查询时,使用的是 快照读 ,它读取的是事务运转的技能 数据的快照 ,因此看不见之前由其他事务提交的新增事务。在使用 update 语句进行更新时,因为要确保更新的数据是基于最新的、还是提交的情状,因此数据库必须进行 现时读 ,因此 update 语句不祥感知到其他事务新提交的那札纪录。何况,当数据库发现新纪录是恰当 update 中的 where 语句,就会对其也进行更新,还会将这札纪录 创建版块 的 trx_id (事务ID)成立为现时更新事务的ID。第二次使用 select 进行查询时,依旧使用的是 快照读 ,快照读的规章是: 只读取在事务运转时就还是提交的数据版块,或者由才智务自己创建的数据版块 ,因此当今不错读取到新纪录。四种破损级别读未提交(READ UNCOMMITTED) - 性能最佳,一致性最差--

    SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

    --

    --

    --

    -- 使用场景:对数据一致性条目极低,照及时性条目极高的监控系统

    {jz:field.toptypename/}

    读已提交(READ COMMITTED) - Oracle/PostgreSQL默许SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

    --

    --

    --

    --

    -- 使用场景:大多数 OLTP 系统

    可重叠读(REPEATABLE READ) - MySQL默许SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

    --

    --

    --

    --

    -- 使用场景:需要事务内数据一致性的场景

    串行化(SERIALIZABLE) - 一致性最佳,性能最差SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;

    --

    --

    --

    --

    -- 用场景:对一致性条目极高,如金融中枢系统

    破损级别实践影响C READ UNCOMMITTED--

    UPDATE account SET balance = 1000.00 WHERE name = '张三'; UPDATE account SET balance = 500.00 WHERE name = '李四'; UPDATE account SET balance = 2000.00 WHERE name = '王五'; DELETE FROM account WHERE name = '赵六';

    --

    SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; START TRANSACTION; --

    SELECT SUM(balance) AS total_before FROM account; -- 假定看到3500

    --

    START TRANSACTION; UPDATE account SET balance = balance -

    -- 还没提交!

    -

    UPDATE account SET balance = balance *

    --

    COMMIT;

    --

    ROLLBACK; -- 转账失败,但利息已乖张计较!

    REPEATABLE READ--

    UPDATE account SET balance = 1000.00 WHERE name = '张三'; UPDATE account SET balance = 500.00 WHERE name = '李四'; UPDATE account SET balance = 2000.00 WHERE name = '王五';

    --

    SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; START TRANSACTION; SELECT SUM(balance) AS total_before FROM account; -- 看到3500

    --

    START TRANSACTION; UPDATE account SET balance = balance -

    COMMIT; -- 提交到手

    --

    SELECT SUM(balance) AS total_now FROM account; --

    UPDATE account SET balance = balance *

    COMMIT; -- 提交后,其他事务看到更新