MySQL的隔离级别是怎么样的?

2 个回答

  • 张三丰
    慢慢理解世界,慢慢更新自己。
    ### 事务的隔离级别 事务的隔离级别定义了事务之间的相互隔离程度,决定了一个事务可以看到另一个事务中的数据变更的程度。以下是四种主要的事务隔离级别: 1. **未提交读 (Read Uncommitted)** - **描述**:允许脏读,即可能读取到其他会话中未提交事务修改的数据。 - **特性**:最低的隔离级别,存在脏读问题。 - **适用场景**:一般不推荐使用,适用于对事务一致性要求不高的场景。 2. **提交读 (Read Committed)** - **描述**:只能读取到已经提交的数据。Oracle 等多数数据库默认都是该级别。 - **特性**:消除了脏读问题,但可能会出现不可重复读问题。 - **适用场景**:多数应用的默认选择,适用于需要一定程度一致性的场景。 3. **可重复读 (Repeatable Read)** - **描述**:在同一个事务内的查询都是事务开始时刻一致的。MySQL 的 InnoDB 默认级别。 - **特性**:消除了不可重复读问题,但可能存在幻读问题。 - **适用场景**:适用于需要一致性较高的场景,避免同一事务内多次读取到不同的数据。 4. **可串行化 (Serializable)** - **描述**:完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞。 - **特性**:最高的隔离级别,完全避免脏读、不可重复读和幻读问题,但并发性能较低。 - **适用场景**:适用于对数据一致性要求极高的场景,通常用于金融系统等关键应用。 ### 不可重复读和幻读的区别 - **不可重复读**:在同一个事务中,两次读取同一条记录的结果不同。解决不可重复读需要锁定当前满足条件的记录。 - **幻读**:在同一个事务中,两次读取结果集的条数不一致(例如插入或删除记录)。解决幻读需要锁定当前满足条件的记录及相邻的记录。 ### 示例 - **不可重复读示例**: ```sql -- 事务1 START TRANSACTION; SELECT * FROM products WHERE id = 1; -- 事务2 START TRANSACTION; UPDATE products SET price = 100 WHERE id = 1; COMMIT; -- 事务1 SELECT * FROM products WHERE id = 1; COMMIT; ``` - **幻读示例**: ```sql -- 事务1 START TRANSACTION; SELECT COUNT(*) FROM products WHERE category = 'electronics'; -- 事务2 START TRANSACTION; INSERT INTO products (name, category) VALUES ('New Product', 'electronics'); COMMIT; -- 事务1 SELECT COUNT(*) FROM products WHERE category = 'electronics'; COMMIT; ``` ### 总结 事务的四种主要隔离级别各有优缺点,开发者应根据具体应用场景选择合适的隔离级别来平衡数据一致性和系统性能: 1. **未提交读 (Read Uncommitted)**:允许脏读,最低隔离级别。 2. **提交读 (Read Committed)**:消除脏读,可能出现不可重复读。 3. **可重复读 (Repeatable Read)**:消除不可重复读,可能出现幻读。 4. **可串行化 (Serializable)**:最高隔离级别,完全避免脏读、不可重复读和幻读,性能较低。
    发布于 2024-07-08 09:31 •IP属地 安徽
    举报
    评论
    收藏

  • 东方朔
    重新审视自己,什么使你快乐,什么就是眼下最珍贵。
    **未提交读** 事务还没有提交的修改,其他事务都可以读取到。可能会有脏读的问题,就是读到一些未提交的脏数据。 **提交读** 其他事务提交的修改,事务在执行过程中可以读取到,如果一个事务在执行过程中需要两次读取同一行数据,可能会不一致。一般发生在UPDATE和DELETE操作。(大部分数据库系统是采用的这个,但是mysql不是) 这个隔离级别下,读是不加锁的,写,更新,删除是加锁的,如果更新的行是可以通过索引查找到,那么是对这些行加行锁,否则会将所有行都加锁,然后返回给MySQL Server,让他来进行过滤,对于不满足条件的行解锁。 但是还是会有幻读的问题发生(幻读就是事务A在读取和写入符合的条件的记录时,其他事务又插入了一条符合条件的记录,此时事务A二次读取时会产生幻行,一般发生在INSERT操作。) 可重复读 在事务开始时,记录当时的状态,在第二次读取同一行数据时,除非是本事务做的修改,否则读取的都是事务开始时的数据。可以解决脏读的问题,没法解决幻读的问题。这是MySQL的默认事务隔离级别。(MySQL在可重复读的隔离级别下,通过MVCC机制和Next-key Lock解决了幻读的问题。) 可串行化 强制事务串行执行,会让读取每一行都加锁,读用读锁,写用写锁,读写锁互斥,可以解决幻读的问题。并发比较多的话可能会造成大量的超时等待和锁竞争。如果业务并发的特别少或者没有并发,同时又要求数据及时可靠的话
    发布于 2022-02-05 08:20 •IP属地 湖北
    举报
    评论
    收藏