MySQL的4种事务隔离级别

317 阅读2分钟

MySQL提供了四种事务隔离级别,分别为:读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)和串行化(Serializable)。下面我将逐一介绍这四种隔离级别,并且给出示例。

  1. 读未提交(Read Uncommitted)

读未提交是最低的事务隔离级别,它允许一个事务读取到另一个事务尚未提交的数据。在这个级别下,不仅可以发生脏读(Dirty Read),还可能出现不可重复读(Non-Repeatable Read)和幻像读(Phantom Read)问题。

示例代码:

// session1 开启事务并修改用户姓名
begin transaction;
update user set name='user1_new' where id=1;

// 在 session2 中查询到未提交的修改
select * from user where id=1;
  1. 读已提交(Read Committed)

读已提交级别允许一个事务只能读取到另一个事务已经提交的数据,可以避免脏读,但可能出现不可重复读和幻像读问题。

示例代码:

// session1 开启事务并修改用户姓名
begin transaction;
update user set name='user1_new' where id=1;
commit;
// session2 查询时只能看到已经提交的修改
begin transaction;
select * from user where id=1;
commit;
  1. 可重复读(Repeatable Read)

在可重复读级别下,事务在执行期间多次读取同一数据时,得到的结果是一致的。可重复读级别解决了不可重复读问题,但可能出现幻像读问题。

示例代码:

// session1 开启事务并查询用户信息
begin transaction;
select * from user where id=1;

// 在 session2 中插入新的用户信息
begin transaction;
insert into user(id,name,age) values(2,'user2',18);
commit;

// session1 再次查询时仍然能看到之前的数据,没有发生幻像读
select * from user where id=1;
commit;
  1. 串行化(Serializable)

串行化是最严格的隔离级别,在这个级别下,所有的事务都只能串行执行,完全避免了并发问题。虽然解决了脏读、不可重复读和幻像读等问题,但会导致很大的性能开销,应该避免使用。

示例代码:

// session1 开启事务
begin transaction;

// 在 session2 中尝试插入新的用户信息,但会被阻塞等待 session1 执行结束
begin transaction;
insert into user(id,name,age) values(2,'user2',18);

需要注意的是,事务隔离级别越高,数据库的并发性能就越低,因此在选择事务隔离级别时,需要根据业务需求和性能要求进行权衡。