数据库事务与数据库锁的理解

之前对数据库事务和数据库锁的概念含糊不清,经过学习发现事务的隔离级别是通过锁的机制实现的,现在就个人理解对此进行总结。

一、事务

事务就是对数据操作的保障,当用户执行一个数据库操作,这些操作要么全部执行,要么全部不执行,这样做可以防止一些不合理的麻烦,比如某一条数据执行失败而其他数据却执行成功导致脏读、对数据进行并行操作导致数据错乱等等。
首先我们需要了解事务的概念,其实无非是一下几点:
1.原子性:比如对多张有关联的表进行删除,相互对应的数据要都删除干净,这个操作其实是一个不可分割的原子单元,只有所有的操作执行成功,整个事务才提交。事务中的任何一个数据库操作失败,已经执行的任何操作都必须被撤销,让数据库返回初始状态。事务中的操作要么都发生,要么都不发生。
2.一致性:事务操作成功后,数据库所处的状态和他的业务规则是一致的,即数据不会被破坏。如A账户转账100元到B账户,不管操作成功与否,A和B账户的存款总额是不变的。
3.持久性:当事务正确完成后,它对于数据的改变是永久性的。
4.隔离性:多个事务并发访问时,事务之间是隔离的,一个事务不应该影响其它事务运行效果。在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间,这个条并发事务所做的修改必须与其他并发事务所做的修改隔离。事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改它之后的状态,不可能查看到两一个事务中间状态的数据。
其中包括四种隔离级别,由低到高依次为:
4.1.读未提交(一个事务可以读到另外一个事务未提交的数据);
4.2.提交读(在一个事务修改数据过程中,如果事务还没提交,其他事务不能读该数据,该级别又称读已提交,顾名思义就是只能读该事务已提交后的数据);
4.3.可重复读(就是在开始读取数据(事务开启)时,不再允许修改操作。由于提交读隔离级别会产生不可重复读的现象,你在读数据的时候别的事务进行修改,会导致读取不一致的情况。所以,比提交读更高一个级别的隔离级别就可以解决不可重复读的问题,但是可重复读无法解决幻读问题,其与脏读并不一样,特别解释一下幻读:幻读是事务非独立执行时发生的一种现象。例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。产生幻读的原因是事务一在进行范围查询的时候没有增加范围锁(range-locks:给SELECT 的查询中使用一个“WHERE”子句描述范围加锁),所以导致幻读)
4.4.可序列化(事务串行化执行,隔离级别最高,牺牲了系统的并发性。最高的隔离级别,前面提到的所有的隔离级别都无法解决的幻读,在可序列化的隔离级别中可以解决。)
举个例子:老板给员工发工资,员工实际工资是一万,财务统计的时候写了一万五,员工看见了很高兴,这就是事务的第一级别:读未提交,这个时候钱还没真的到卡上,他看到的是未提交的数据。但是财务上报后领导确认发现写错了,改成了一万提交给银行后,员工查询银行卡发现只有一万块,这是第二级别:读已提交,他看到的是已提交的数据。之后员工去消费,在刷卡的时候他花了一千,但是他女朋友刚好用他的银行卡刷了两千,在一千的基础上莫名其妙新增了两千,他看见扣了三千块钱很疑惑,这是第三隔离级别:重复读。之后他进行一系列操作,让他在使用银行卡的时候,别的人无法登录他的银行卡,这就是最高隔离级别:序列化,一次只能一个人进行操作。

二、数据库锁

首先要区分数据库锁和线程锁(两者的悲观锁、乐观锁的概念很容易搞混),现在对数据库锁进行总结:
1.悲观锁:悲观锁是指假设并发操作会发生冲突,所以不管冲突是否真的发生,都会使用锁机制。比如,悲观锁可以帮助正在执行的事务锁住读取的记录,防止其它事务读取和更新这些记录。其它事务会一直阻塞,直到这个事务结束。悲观锁是在使用了数据库的事务隔离功能的基础上,独享占用的资源,以此保证读取数据一致性,避免修改丢失。
在数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁),它们都属于悲观锁。
1.1.共享锁(S锁):用于不更改或不更新数据的操作(只读操作),如 SELECT 语句。若事务T1对数据对象A加上共享锁,则事务T1只能读A;其他事务T2、T3也都只能再对A加共享锁进行只读操作,而不能加排他锁,想要加排他锁除非T1释放A上的共享锁。这就保证了其他事务可以读A,但在T1释放A上的共享锁之前不能对A做任何修改。
1.2.排他锁(X锁):用于数据修改操作,例如 INSERT、UPDATE 或 DELETE。可以确保不会同时对同一资源进行多重操作。如果事务T1对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获准排他锁的事务T1既能读数据,又能修改数据,其他任何事务都不能对A进行读取和修改。

当数据对象被加上排它锁时,其他的事务不能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。数据库利用这两种基本的锁类型来对数据库的事务进行并发控制,所以说事务基于数据库锁,严格来说是事务基于悲观锁机制。
2.乐观锁:乐观锁不会锁住任何东西,也就是说,它不依赖数据库的事务机制,乐观锁不是数据库自带的,乐观锁完全是应用系统层面的东西,需要我们自己去实现。乐观锁是指操作数据库时(更新操作),想法很乐观,认为这次的操作不会导致冲突,在操作数据时,并不进行任何其他的特殊处理(也就是不加锁),而在进行更新后,再去判断是否有冲突了。
事务隔离级别是并发控制的整体解决方案,其实际上是综合利用各种类型的锁和行版本控制来解决并发问题。当然数据库锁有很多种,同时还包括一些行锁和表锁、页面锁等等。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值