美文网首页数据库
数据库事务和四种隔离级别

数据库事务和四种隔离级别

作者: 宇晨棒棒的 | 来源:发表于2019-07-11 18:00 被阅读0次

    1.什么是事务?

    访问并可能更新数据库中各种数据项的一个程序执行单元(unit),它通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起。当在数据库中更改数据成功时,在事务中更改的数据便会提交,不再改变。否则,事务就取消或者回滚,更改无效。

    数据库事务正是用来保证数据操作的平稳性和可预测性的技术

    2.事务解释:要做的或所做的事情

    3.事务的本质:一系列操作

    4.事务特征:恢复和并发控制的基本单位

    5.事务的属性:原子性,隔离性,一致性,持久性.------->ACID

    1)原子性:一个事务是一个不可分割的整体,为了保证事务的总体目标,事务必须具有原子性,即当数据修改时,要么全都执行,要么全都不执行。即,不允许事务部分地完成,避免了只执行这些操作的一部分而带来的错误

    2)一致性:一个事务在执行之前和执行之后,数据库数据必须保持一致性。数据库的一致性状态应该满足模式锁指定的约束条件,那么在完整执行该事务后,数据库仍然处于一致性状态

    例如:银行转账,转账前后两个账户金额之和应保持不变

    3)隔离性:由并发事务所作的修改必须与任何其它并发事务所作的修改隔离。事务查看数据库时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据

    4)持久性:事务完成以后,DBMS(数据库管理系统)保证它对数据库中数据的修改是永久性的,当系统或介质发生故障时,该修改也永久保持。持久性一般通过数据库备份与恢复来保证.

    一般情况下,通过执行COMMIT(提交)或ROLLBACK(回滚)语句来终止事务。当执行COMMIT语句时,自从事务启动以来对数据库所做的一切更改就成为永久性的,即被写入到磁盘,而当执行ROLLBACK语句时,自从事务启动以来对数据库所做的一切更改都会被撤销,并且数据库中内容返回到事务开始之前所处的状态。无论什么情况,在事务完成时,都能保证回到一致性状态。

    6.事务执行的方式

    1)串行控制:如果事务是顺序执行的,即一个事务完成之后再进行下一个事务.

    2)并行控制:同时接受多个事务,并且这些事务在时间上可以重叠执行,但是并发操作有可能会破坏其ACID特性.

    7.并发控制带来的数据不一致性的种类:

    1)脏读------>事务未commit,另一个事务读取数据

    一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。

    2)不可重复读

    一个事务对同一行数据重复读取两次,但是却得到了不同的结果.

    两种现象:

    A.虚读:

    事务T1读取某一数据后,事务T2对其做了修改,当事务T1再次读取该数据时得到与前一次不同的值

    B.幻度:

    事务在操作过程中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据或者缺少了第一次查询中出现的数据。这是因为在两次查询过程中有另外一个事务插入数据造成的

    3)更新丢失

    两个事务都同时更新一行数据,一个事务对数据的更新把另一个事务对数据的更新覆盖了

    8.避免上面出现的问题,提出了4种事务隔离机制

    1)读未提交(Read Uncommitted):

    只处理更新丢失。如果一个事务已经开始写数据,则不允许其他事务同时进行写操作,但允许其他事务读此行数据。可通过“排他写锁”实现

    实例:公司发工资,领导把100元打到了小王的账号上,但是没有提交事务,小王正好查看余额,发现工资是100,非常高兴.但是领导发现发给小王的工资金额不对,工资应该是50,于是回滚了事务,修改了吟哦,在提交了事务,最后实际金额是50,小王空欢喜了.

    出现上述情况:这就是脏读的现场,事务B读取了事务A未提交的数据.

    因此,读未提交会出现脏读的现象.

    2)读提交(Read Committed):

    处理更新丢失、脏读。读取数据的事务允许其他事务继续访问改行数据,但是未提交的写事务将会禁止其他事务访问改行。可通过“瞬间共享读锁”和“排他写锁”实现.

    实例:小王去吃饭结账,系统读取卡里有50,而此时他的老婆也正好在网上转账,把小王工资卡的50元转到另一账户,并在小王之前提交了事务,当小王扣款时,系统检查到小王的工资卡已经没有钱,扣款失败,小王十分纳闷,明明卡里有钱,为什么会出现这个问题.

    出现这个情况:这就是不可重复读取现象,两个并发的事务,“事务A:小王消费”、“事务B:小王的老婆网上转账”,事务A事先读取了数据,事务B紧接了更新了数据,并提交了事务,而事务A再次读取该数据时,数据已经发生了改变。

    因此:Read committed 时,避免了脏读,但是可能会造成不可重复读

    3)可重复读取(Repeatable Read):

    处理更新丢失、脏读和不可重复读取。读取数据的事务将会禁止写事务,但允许读事务,写事务则禁止任何其他事务。可通过“共享读锁”和“排他写锁”实现

    实例: 当隔离级别设置为Repeatable read 时,可以避免不可重复读。当小王拿着工资卡去消费时,一旦系统开始读取工资卡信息(即事务开始),小王的老婆就不可能对该记录进行修改,也就是小王的老婆不能在此时转账。

    虽然Repeatable read避免了不可重复读,但还有可能出现幻读 

    小王的老婆工作在银行部门,她时常通过银行内部系统查看小王的信用卡消费记录。有一天,她正在查询到小王当月信用卡的总消费金额 (select sum(amount) from transaction where month = 本月)为80元,而小王此时正好在外面胡吃海塞后在收银台买单,消费1000元,即新增了一条1000元的消费记录(insert transaction ... ),并提交了事务,随后小王的老婆将小王当月信用卡消费的明细打印到A4纸上,却发现消费总额为1080元,小王的老婆很诧异,以为出 现了幻觉,幻读就这样产生了。

    4)序列化(Serializable):

    提供严格的事务隔离,执行串行控制。要求失去序列化执行,事务只能一个接一个地执行,不能并发执行。仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。

    在该级别下,事务顺序执行,不仅可以避免脏读、不可重复读,还避免了幻像读.

    9.数据库事务隔离级别由低到高依次为:

    Read uncommitted <  Read committed <Repeatable read <Serializable

    读未提交  < 读提交 < 可重复读取 < 序列化

    10.隔离级别中可能出现的问题

    隔离级别中出现的问题汇总.

    11.隔离级别总结:

    隔离级别越高,越能保证数据的完整性和统一性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed。它能够避免脏读,而且具有较好的并发性能。尽管它会导致不可重复读、幻读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制

    相关文章

      网友评论

        本文标题:数据库事务和四种隔离级别

        本文链接:https://www.haomeiwen.com/subject/xjckkctx.html