mysql事务隔离级别

事务隔离级别越高, 越能保证数据的完整性和一致性, 但是对并发性能的影响也会越大。 MySQL事务包含如下4个隔离级别, 按隔离级别从低到高排列如下。

(1) read uncommitted(dirty read)
read uncommitted也称为读未提交, 事务可以看到其他事务更改了但还没有提交的数据, 即存在脏读的情况。
(2) read committed
read committed也称为读提交, 事务可以看到在它执行的时候, 其他事务已经提交的数据, 已被大部分数据库系统采用。 允许不可重复读, 但不允许脏读, 如下语句。
begin transaction;
select a from b where c=1;
… #其他事务更改了这条记录
,并且
commit提交
select a from b where c=1; #可以看到新的数据, 不可重复读
end
(3) repeatable read
repeatable read也称为可重复读。 同一个事务内, 同一个查询请求, 若多次执行, 则获得的记录集是相同的, 但不能杜绝幻读, 示例如下。
begin transaction
select a from b where c=1;
… #其他事务更改了这条记录
,并且
commit
select a from b where c=1; #仍然看到旧的数据
,可重复读
,但不能杜绝幻读
end
发生幻读的场景有, 某事务A按某个条件进行查询, 此时尚未提交。 然后另一个事务成功插入了数据。 事务A再次查询时, 可能会读取到新插入的数据。

MySQL InnoDB引擎默认使用的是repeatable read(可重复读) 。 当事务A发出一个一致性读之时, 即一个普通的SELECT语句, InnoDB将给事务A一个时间点。 如果另一个事务在该时间点被指定之后删除一行并提交, 则事务A看不到该行已被删除。
插入和更新的处理与此相似。 可以通过提交事务来前进时间点, 然后进行另一个SELECT。 这被称为多版本并发控制(multiversioned concurrency control) 。 如果想要查看数据库的最新状态, 应该用READ COMMITTED隔离级别或用一个锁定
读“SELECT*FROM t LOCK IN SHARE MODE;”。
为了满足可重复读, 事务开启后, 对于要查询的数据, 需要保留旧的行版本, 以便重新查询, 这在一些特殊的环境中可能会导致某些问题, 比如一些框架, 对于任何操作, 都要先进入AUTOCOMMIT=0的模式, 直到有写入时才会进行COMMIT提交, 这可能会导致事务数过多, 有时由于框架或编码的不完善, 可能会出现长时间不提交的事务, 导致UNDO保留的旧的数据记录迟迟不能被删除, 还可能导致UNDO空间暴涨。 对于这些极端情况, 首先应该考虑调整应用, 实在没有办法的话, 可以考虑将事务的隔离模式更改为read committed。

(4) serializable
serializable也称为序列化, 最高级别的锁, 它解决了幻读, 它将锁施加在所有访问的数据上。
该锁将把普通的SELECT语句默认改成SELECT…LOCK IN SHARE MODE。 即为查询语句涉及的数据加上共享琐, 阻塞其他事务修改真实数据。
如下的命令语句可查询当前的事务隔离级别。
mysql> show variables like ‘%tx%’;
+———————+———————-+
| Variable_name | Value |
+———————+———————-+
| tx_isolation | REPEATABLE-READ |
+———————+———————-+
1 row in set (0.00 sec)
或者
mysql> SELECT @@global.tx_isolation, @@session.tx_isolation;
+——————————-+———————————+
| @@global.tx_isolation | @@session.tx_isolation |
+——————————-+———————————+
| REPEATABLE-READ | REPEATABLE-READ |
+——————————-+———————————+
设置事务隔离级别的语法格式如下。
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL
{ READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
在配置文件内修改mysqld节的transaction-isolation参数的方式如下。
[mysqld]
transaction-isolation = {READ-UNCOMMITTED | READ-COMMITTED
| REPEATABLE-READ | SERIALIZABLE}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值