[关闭]
@boothsun 2018-02-28T09:58:40.000000Z 字数 2624 阅读 1065

数据库基础知识

MySQL


事务

事务特性

原子性(atomicity):

一个事务必须是一个不可分割的最小单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作,这就是事务的原子性。

一致性(consistency):

一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。

拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。

隔离性( Isolation):

多个并发事务之间相互隔离,互不干扰。两个事务T1和T2,在T1未提交前,T1所在的修改对于T2来说是不可见的,因为T1可能会发生回滚,此时T2读到的数据是脏读。

持久性( Durability):

一个事务一旦被提交了,则其所做的修改就会被永久保存到数据库中。即使是在数据系统遇到故障的情况下也不会丢失事务所进行的操作。

事务所作的修改一旦提交后即是物理修改,而非逻辑修改。

事务隔离级别

Read uncommitted(读 未提交) —— 脏读

一个事务可以读取另一个事务修改但未提交的数据。这种情况 会造成脏读的问题。

Read committed (读 提交) —— 不可重复读

一个事务从开始到结束过程中,可以读到其他事务修改且已提交的操作。这会造成,事务进行过程中,两次读到的数据不一致,从而造成不可重复读的问题。

REPEATABLE READ( 可重复读): —— 幻读

该级别保证了在同一个事务中多次读取同样记录的结果是一致的。但是理论上,可重复读隔离级别还是无法解决另一个幻读的问题。所谓幻读,指的是当某个事务在读取某个范围内的记录时,另一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行的问题。

可重复读是MySQL的默认事务隔离级别。

SERIALIZABLE(串行化):—— 依靠数据行加锁实现的

强制事务串行化执行。简单来说,SERIALIZABLE会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争用的问题。

事务读取过程中常见的问题

脏读:

一个事务在处理过程中读取了另一个事务修改但尚未提交的数据。脏读是没有问题的,问题在于:另一个事务可能存在回滚的风险。

不可重复读:

一个事务处理过程中,多次查询却返回了不同的数据值。
例如事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,此时就是发生了不可重复读现象。

不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。

一个事务过程中,两次读到的数据不一致。

幻读:

所谓幻读,指的是当第一个事务对一个表中的数据进行了修改,比如这种修改涉及到表中的“全部数据行”。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入“一行新数据”。那么,以后就会发生操作第一个事务的用户在事务提交后发现表中还存在没有修改的数据行,就好象发生了幻觉一样。

加锁读:

在事务范围内读取的每一行数据上都加锁,所以可能导致大量的锁争抢和超时等问题。

并发事务强制串行化!

MYSQL隔离界别与事务过程 常见问题

隔离级别 脏读 不可重复读 幻读 加锁读
READ UNCOMMITTED YES YES YES NO
READ COMMITTED YES YES YES NO
REPEATABLE READ NO NO YES NO
SERIALIZABLE NO NO NO NO

事务相关语句

开始事务:BEGIN TRANSACTION
提交事务:COMMIT TRANSACTION
回滚事务:ROLLBACK TRANSACTION

事务分类

扁平事务:

事务要么都执行,要么都回滚,也就是我们最常见、最常使用的事务。扁平化事务只能以COMMIT或者ROLLBACK结束。

带有保存点的扁平事务:

假设事务的操作过程有begin,A,B,C,D,COMMIT 几个过程,那么带有保存点的扁平事务过程大致如下:
begin --> 隐含保存点1(save work 1) --> A --> B(save work2)--> C --> D(rollback work2) --> commit。

上述过程中如果遇到rollback work2,只需要回滚到保存点2,不需要全部回滚。

简单来说,带有保存点的扁平事务就是有针对的回滚操作。

缺点:带有保存点的扁平事务,当发生系统崩溃时,所有的保存点都将消失,因为其保存点是易失的(volatile),而非持久的(persistent)。这意味着当进行恢复时,事务需要从开始处重新执行,而不能从最近的一个保存点继续执行。

链事务:

链事务提交一个事务时,释放不需要的数据对象,然后将必要的处理上下文隐式地传递给下一个要开始的事务。注意,提交事务操作和开始下一个事务操作将合并为一个原子操作。这意味着下一个事务可以看到上一个事务的结果,就好像在一个事务中。

带有保存点的扁平事务可以回滚到任意正确的保存点,链事务只能回滚到当前事务,即只能恢复到最近一个的保存点。

扁平事务全程持有锁,链事务在执行commit后即释放了当前事务所持有的锁。

链事务如下:T1 --> T2 --> T3

嵌套事务:

可以理解为一棵事务树,顶层事务控制着下面各个层次的子事务,所有的叶子节点都是扁平事务,实际工作是由叶子节点完成的。子事务既可以提交也可以回滚。但是它的提交操作并不马上生效,除非其父事务已经提交。

也就是说,任何子事务都在顶层事务提交后才真正的提交。树中的任意一个事务的回滚会引起它的所有子事务一同回滚,故子事务仅保留A、C、I特性,不具有D的特性。

分布式事务:

分布式环境下运行的扁平事务。

InnoDB支持链事务和扁平事务。

数据库范式

第一范式

数据表中的每一列都是不可分割的原子数据项。

不可分割的原子项

第二范式

在第一范式的基础上,非主属性必须完全依赖于候选码。所谓完全依赖是指不能存在仅依赖于部分候选码的属性。如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的唯一标识。简而言之,第二范式就是在第一范式的基础上非主属性完全依赖于候选码。

不存在部分依赖。

第三范式

符合第1和2范式的基础上,消除传递依赖。

不存在传递依赖。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注