欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

MySQL事务隔离级别

程序员文章站 2022-06-02 23:39:44
...

事务并发导致的问题是数据库需要重点解决的问题,关于事务处理的技术都已经非常成熟了,四种隔离级别再加上一个快照是所有数据库

mysql> commit

-> ;

Query OK, 0 rows affected (0.04 sec)


mysql> select * from innodb where;

+------+------+

| name | age |

+------+------+

| fzj | 25 |

+------+------+

1 row in set (0.00 sec)

即便是A事务提交了,B事务查询的结果仍然不受干扰,这是可重复读隔离级别的典型特性。可是如果 B事务也要更新同一条记录怎么办?基于这个数字会导致A事务更新的丢失。

mysql> update innodb set age=age+5 where;

Query OK, 1 row affected (0.00 sec)

Rows matched: 1 Changed: 1 Warnings: 0


mysql> select * from innodb where;

+------+------+

| name | age |

+------+------+

| fzj | 35 |

+------+------+

1 row in set (0.00 sec)

可见A事务的更新并没有丢失。如果在A事务未提交之前,B事务更新同一条记录会导致B事务被阻塞,update需要对相应行加上行锁,这种排他 锁是独占性的。

2>解决幻读问题

mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)


mysql> insert into innodb values('ecy', 25);

Query OK, 1 row affected (0.00 sec)


mysql> start transaction;

Query OK, 0 rows affected (0.04 sec)


mysql> select count(*) from innodb;

+----------+

| count(*) |

+----------+

| 1 |

+----------+

1 row in set (0.02 sec)

mysql> commit

-> ;

Query OK, 0 rows affected (0.05 sec)


mysql> select count(*) from innodb;

+----------+

| count(*) |

+----------+

| 1 |

+----------+

1 row in set (0.00 sec)

可见A事务成功地插入了一条记录,因为 它没有同B事务竞争锁,所以A事务插入记录和B事务更新记录可以同时进行,可是A事务提交之后并没有导致B事务幻读,MySQL的可重复读隔离级别确实能 避免幻读。


3>serializable隔离级别

serializable隔离级别是最高的隔离级别,一个事务中的查询语句会给相应的行加上排他锁,直到事务结束。

mysql> set session transaction isolation level serializable;

Query OK, 0 rows affected (0.00 sec)

mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)

mysql> update innodb set age=age+6 where;

Query OK, 1 row affected (0.00 sec)

Rows matched: 1 Changed: 1 Warnings: 0


mysql> set session transaction isolation level serializable;

Query OK, 0 rows affected (0.00 sec)

mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from innodb where;

B事务此时会被阻塞,因为A事务要跟新'fzj'这一行,因此给这行加上了排它锁,B事务再将给 其加上共享锁将会失败。使用A事务commit之后,B事务才会往下执行(我发现让我吃惊的行为,在B事务中即使查询name='ecy'这行,B事务也 会被阻塞,难道使用了表锁定??)。比较REPEATABLE-READ隔离级别可以发现,在可重复读隔离级别不会给查询语句加上共享锁,,如果需要的话可 以显示地使用select ... lock in share mode和select ... for update分别加上共享锁和排他锁。