mysql中的基本术语

1.读写锁

  假设有一张用户表,里面有100条数据,id分别为1-100。现有十个人同时查询数据库(select * from user;),那么不会出现任何问题,每个人查到的数据都是相同的。但是如果有九个人查询数据库(select * from user;),一个人从数据库中删除id为1的用户的数据(delect from user where id=1;),那么会出现什么情况呢,也许查询的九个人查到了错误的数据,有可能系统出错。我们无法预见,肯定不能允许这种情况发生。

  解决这种问题的方法是并发控制,在处理并发读或者写时,用两种类型的锁组成的锁系统来解决问题。分别是共享锁和排它锁,又称为读锁和写锁。读锁是共享的,互不阻塞的,多个用户可以同时读取同一个资源,互不干扰。写锁是排他的,一个写锁会阻塞其他读锁和写锁,这样可以保证在某一时刻,只有一个用户改变数据,并防止其他用户读取正在改变的数据。

2.锁粒度

  加锁可以保持系统的稳定性,但是加锁也会消耗系统资源,锁的各种操作,包括获得锁,检查锁是否已经解除,释放锁等都会增加系统的开销。如果系统花费大量时间来管理锁,而不是存取数据,那么系统的性能会受到很大的影响,所以尽量之锁定需要修改的部分数据,而不是所有的资源。更理想的方式是,支队会修改的数据片进行精确的锁定。

  表锁(table lock)

  表锁是MySQL的最基本的锁策略,是开销最小的策略。它会锁定整张表,用户在对表进行写操作前,需要先获得写锁,这会阻塞其他用户对该标的所有读写操作。只有没有写锁是,其他读取的用户才能获得读锁,读锁之间是不互相阻塞的。

  行锁(row lock)

  行锁最大程度上地支持并发处理,同时也带来了最大的锁开销。

3.事务

  事务就是一组原子性的sql操作,如果这一组语句都执行成功,就会执行,有任何一套语句出错,所有的语句就都不执行。可以类比去ATM转账给我,假设要转1000元,首先ATM要查询你的账户余额是否大于等于1000,然后从你的账户里扣除1000元,然后向我的账号里充值1000元。假如在第二步结束之后,ATM突然出现故障,那么你的账户里少了1000元,我的账户却没有多出1000元,这种情况肯定是不能发生的。

  事务要满足ACID,原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。

  原子性:一个事务包含多个操作,这些操作要么全部执行,要么全都不执行。实现事务的原子性,要支持回滚操作,在某个操作失败后,回滚到事务执行之前的状态。

  一致性:  一致性是指事务使得系统从一个一致的状态转换到另一个一致状态。

  隔离性:并发事务之间互相影响的程度,比如一个事务会不会读取到另一个未提交的事务修改的数据。不同的存储引擎有不同的隔离级别。

   持久性: 事务提交后,所做的修改会永久保存在数据库中,及时此时系统崩溃,修改的数据也不会丢失。

4.隔离级别

  sql标准中定义了四种隔离级别。分别是未提交读(read uncommitted),已提交读(read committed),可重复读(repeatable read),可序列化(serializable)。

  未提交读:事务中的修改,即使没有提交,对其他操作也是可见的。其他事务可以读取到未提交的数据,称为脏读(dirty read)。会导致很多问题,实际应用很少。

  已提交读:一个事务在开始到提交之前,对其他事务都是不可见的。 也叫做不可重复读(nonrepeatable read),在事务提交前后读到的数据不同。Oracle默认隔离级别,Oracle只支持已提交读和可序列化。

  可重复读:事务A读取与搜索条件相匹配的若干行。事务B以插入或删除行等方式来修改事务A的结果集,然后再提交。事务A再读取时,却发现数据发生了变化。造成了幻读。(MySQL默认的隔离级别)

  可序列化:给每一个读操作都加上行锁,保证不会出现脏读,不可重复读,幻读。但是开销非常大,很少使用。

5.死锁

  死锁是指两个或多个事务在统一资源上互相占用,并请求锁定对方正在占用的资源。假设有这样两个事务:

  事务A:

  start transaction;

  update user set name="张三" where id=1;

  update user set name="李四" where id=2;

  commit;

  事务B:

  start transaction;

  update user set name="王五" where id=2;

  update user set name="赵六" where id=1;

  commit;

  如果两个事务同时执行完第一条update语句,都准备执行第二条update语句,但是第二行的数据都被对方锁定,都在等待对方释放锁,又持有对方需要的锁,就形成了死锁。

  死锁发生以后,只有部分或完全回滚其中一个事务,才能打破死锁。innoDB处理死锁的方法是,将持有最少行级排它锁的事物进行回滚。

6.多版本并发控制

  MySQL的大多数事务型存储引擎实现的都不是简单的行级锁。基于提升并发性能的考虑,它们一般都同时实现了多版本并发控制(MVCC),各种数据库系统实现MVCC的机制不尽相同。可以认为MVCC是行级锁的一个变种,但是它在很多情况下避免了加锁操作,开销更低,虽然实现机制有所不同,但大都实现了非阻塞的读操作,写操作也之锁定必要的行。 MVCC的实现是通过保存数据在某个时间点的快照来实现的。不管需要执行多长时间,每个事务看到的数据都是一致的。根据事务开始的时间不同,每个事务对同一张表,同一时刻看到的数据可能会不一样。

转载于:https://www.cnblogs.com/leeshuai/p/8316045.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值