数据库之什么是事物

什么是事物?

就是把多件事情当做一件事来处理。大家都是绑在同一条船上的蚂蚱,要生一起生,要死一起死~
下面是具体的定义
事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并用形如begin transaction和end transaction语句(或函数调用)来界定。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。
例如:在关系数据库中,一个事务可以是一条SQL语句,一组SQL语句或整个程序。事务是恢复和并发控制的基本单位。

事物的四个特性(ACID)

1.原子性(atomicity)

一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。

2.一致性(consistency)

事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。

3.隔离性(isolation)

一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

4.持久性(durability)

持续性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
PS:事务只能保证数据库的高可靠性,即数据库本身发生问题后,事务提交后的数据仍然能恢复;而如果不是数据库本身的故障,如硬盘损坏了,那么事务提交的数据可能就丢失了。这属于『高可用性』的范畴。因此,事务只能保证数据库的『高可靠性』,而『高可用性』需要整个系统共同配合实现。(ps地址

举个栗子

我为什么要使用事务? 俺这里再举个很俗很俗的例子:
俺到银行存钱,于是有这么几个步骤:
1、把钱交给工作人员;2、工作人员填单;3、将单子给我签字;4、工作人员确认并输入电脑。

要是,要是我把钱交给工作人员之后,进行到3我签字了。那哥们突然心脏病发作,over掉了,那,我的钱还没有输入电脑,但我却交了钱又签字确认了,而并没有其他任何记录。我岂不是要亏死了???我的血汗钱啊!赶紧退给我!!

于是,在数据库里产生了这么一个术语:事务(Transaction),也就是要么成功,要么失败,并恢复原状。

事物的分类

扁平事物

  • 它是实际生产环境中最常用、最简单的事务类型。
  • 事务从BEGIN WORK开始,从COMMIT WORK或ROLLBACK WORK结束。
  • 发生错误时回滚到事务的起始位置,无法回滚部分操作。而回滚所有的操作开销太大。

带有保存点的扁平事务

  • 这种事务能设置多个保存点,当发生错误时可以回滚到事务中指定的保存点,而不需要将整个事务回滚。

链事务

嵌套事务

分布式事务


并发中事物引起的问题

在并发操作中,如果不考虑事务的隔离性,会引起一系列的问题,如脏读、不可重复读、幻读等。

1.脏读

脏读是指一个事务在处理过程中,读到了另一个未提交的事务中的数据。举个栗子,A向B转账100元这个事务需要两条SQL语句,首先给B的账户添加100元,A的账户减少100元,假如执行完第一条SQL语句后发生了阻塞,此时B对其账户进行查询操作,发现其账户已经多出了100元,但是此时事务阻塞结束,执行第二条语句时,发生了问题,这时数据库就需要回滚数据,返回事务执行之前的状态,那么B的账户会再减少100元,那么之前B查询到的多出100元的结果就是脏读。

2.不可重复读

不可重复读是指在一个事务中读取了两次同一个数据,但是结果不一致,这是因为这个事务两次查询操作之间的时候被另外一个事务修改了数据。举个栗子,事务A进行了两次查询账户的操作,事务B对账户进行了修改操作,改为减少100元,那么在A事务第一次查询账户后如果发生阻塞,B事务此时开启并执行,那么再执行A事务的第二次操作时,就会发现账户少了100元,这就是发生了不可重复读。

不可重复读与脏读的区别是,脏读是A事务读取了B事务未提交的数据,不可重复读是读取了B已提交的数据。

3.幻读

幻读是指在一个事务的操作后发现了未被操作的数据。什么意思呢,还是举个栗子吧,比如A事务想把所有人的账户数据全部改为100元,但此时事务B对该表进行了一个插入操作,增加了一个人Q和账户200元,也就是表增加了一行,那么A事务执行完毕后,会发现有一个人的账户未被修改过,这就是发生了幻读。

幻读和不可重复读都是读取了另一个已经提交的事务,不可重复读的重点在于update和delete,而幻读的重点是insert。

事物的隔离级别

数据库事务的隔离级别有4个,由低到高依次为Read uncommitted 、Read committed 、Repeatable read 、Serializable ,这四个级别可以逐个解决脏读 、不可重复读 、幻读 这几类问题。

1.Read uncommitted 读未提交

在该级别下,一个事务对一行数据修改的过程中,不允许另一个事务对该行数据进行修改,但允许另一个事务对该行数据读。
因此本级别下,不会出现更新丢失,但会出现脏读、不可重复读。

2.Read committed 读提交

在该级别下,未提交的写事务不允许其他事务访问该行,因此不会出现脏读;但是读取数据的事务允许其他事务的访问该行数据,因此会出现不可重复读的情况。

3.Repeatable read 重复读

在该级别下,读事务禁止写事务,但允许读事务,因此不会出现同一事务两次读到不同的数据的情况(不可重复读),且写事务禁止其他一切事务。

4.Serializable 序列化

该级别要求所有事务都必须串行执行,因此能避免一切因并发引起的问题,但效率很低。

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

最后

例子源于网络,如有侵权,请联系删除~
参考:
十一月上
凌澜星空

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值