锁问题

2020-05-06  本文已影响0人  lsh的学习笔记

锁会带来三种问题。

1. 脏读

在不同的事务下,当前事务可以读到另外事务未提交的数据。

示例
发生的条件

事务隔离级别为:Read uncommitted。

使用场景

主从复制环境中,slave节点可以设为Read uncommitted。

2. 不可重复读

在一个事务内多次读取同一数据集合。在这个事务还没有结束时,另外一个事务也访问该同一数据集合,并做了一些DML操作。因此,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据不一样的情况,这种情况称为不可重复读

示例
和脏读的区别

脏读是读到未提交的数据,而不可重复读读到的却是已经提交的数据,但是其违反了数据库事务一致性的要求。

一般来说,不可重复读的问题是可以接受的,因为其读到的是已经提交的数据,本身并不会带来很大的问题。因此,很多数据库厂商(如Oracle、MicrosoftSQLServer)将其数据库事务的默认隔离级别设置为READCOMMITTED,在这种隔离级别下允许不可重复读的现象

3. 丢失更新

一个事务的更新操作会被另一个事务的更新操作所覆盖,从而导致数据的不一致。

要避免丢失更新发生,需要让事务在这种情况下的操作变成串行化,而不是并行的操作。

即对用户读取的记录加上一个排他X锁,注意这需要在同一个事务中,然后再更新,提交事务之后,才会释放排他锁。

处理方法

举例:

begin;
-- 查询的时候,在后面加上 for update,即加排他锁;
select * from account where id = 10 for update;

-- update
update account set balance = 30000 where id = 10;
commit;
上一篇 下一篇

猜你喜欢

热点阅读