@lzb1096101803
2016-03-04T23:49:20.000000Z
字数 2548
阅读 536
面试
数据库
什么是事务
事务是什么的基本单位?恢复和并发控制
事务是恢复和并发控制的基本单位,是用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位。
事务的特性ACID
原子性Atomicity,一致性Consistency,隔离性Isolation,持续性Durability
事务的原子性指的是,事务中包含的程序作为数据库的逻辑工作单位,它所做的对数据修改操作要么全部执行,要么完全不执行。
事务的一致性指的是,在一个事务执行之前和执行之后数据库都必须处于一致性状态。这种特性称为事务的一致性。假如数据库的状态满足所有的完整性约束,就说该数据库是一致的。拿银行转账来说,一致性要求事务的执行不应改变A、B 两个账户的金额总和
隔离性指并发的事务是相互隔离的。即一个事务内部的操作及正在操作的数据必须封锁起来,不被其它企图进行修改的事务看到。4种。
持久性意味着当系统或介质发生故障时,确保已提交事务的更新不能丢失。即一旦一个事务提交,DBMS保证它对数据库中数据的改变应该是永久性的,所以一旦一个事务被提交,DBMS必须保证提供适当的冗余,使其耐得住系统的故障。所以,持久性主要在于DBMS的恢复性能。
恢复使用的技术
冗余(数据转储,日志文件)
并发控制的作用
保证事务的隔离性和一致性
并发控制采用的方法
封锁,时间戳,乐观控制法,多版本并发控制
基本锁的类型和特点
排他锁(写锁):事务T对数据对象A加上X锁,其他事务在T释放A上的锁之前不能再读取和修改A
共享锁(读锁):事务T对数据对象A加上S锁,其他事务可以读A,但在T释放A上的S锁前不能对A进行修改
并发操作带来的数据不一致情况:3种
丢失修改,不可重复读,读'脏'数据
还要知道什么是幻影现象
总的说,数据库事物无非就两种:读取事物(select)、修改事物(update,insert)。在没有事物隔离控制的时候,多个事物在同一时刻对同一(数据的操作可能就会影响到最终期望的结果,通常有四种情况
(1) 两个更新事物同时修改一条数据时,很显然这种情况是最严重的了,程序中无论如何也不能出现这种情况,因为它会造成更新的丢失!通俗的讲,我更新时,你丫也更新这不就出问题了吗,艹,不行!
(2) 一个更新事物更新一条数据时,另一个数据读取了还没提交的更新,这种情况下会出现读取到脏数据。通俗的讲就是,丫的,让你在我更新的时候读取,老子还没提交你丫就读,活该吧,老子提交前又修改了数据,你丫读到脏数据了,活该!
(3) 一个读取事物读取一条数据时另一个更新事物修改了这条数据,这时就会出现不可重现的读取。通俗的讲,麻痹的,老子读数据呢,谁让你丫的修改了,艹,害老子读了不一样的数据。
(4)一个读取事物读取时,另一个插入事物(注意此处时插入,三中时更新同一条数椐,自己体会)插入了一条新数据,这样就可能多读出一条数据,出现幻读。通俗的讲,哥们我读取数据的时侯你插入新数据了是的?怪不得多读了一条呢还以为中奖了呢!FUCK!
以上四种情况描述完毕,相信大家也发现规律了,前三种是对同一条数据的并发操作,对程序的结果可能产生致命影响,尤其是金融等实时性,准确性要求极高的系统,绝不容许这三中情况的出现,相比第四种情况不会影响数据的真实性,在很多情况下是允许的,如社交论坛等实时性要求不高的系统!
综上四个情况,我们可以大致这样简单的理解(最初说的两种事物的自由组合2*2=4):
A) 修改时允许修改(丢失更新)
B) 修改时允许读取(脏读)
C) 读取时允许修改(不可重复读)
D) 读取时允许插入(幻读)
从上到下问题越来越不严重,但所需的性能开销却越大。因为不同的系统允许不同级别的情况,所以就出现了事务隔离这么一个东东,来允许我们设定数据库的并发行为。
其中
1)读取未提交(Read uncommitted), 这个级别就是一个事物更新的时候不允许更新,但允许读取,所以不会出现丢失更新,但会出现脏读。隔离级别最低。
2)读取已提交数据(Read committed),就是一个事物更新的时候不允许读取,必须等到更新事物提交后才能读取,不会出现脏读,但可能出现不可重复度。隔离级别次低。
以上两种级别是针对更新事物的限制,在读取事物进行时,是不会有任何限制的。所以会出现不可重复读(读取时,有更新),和幻读(读取时,插入)。
3)可重现的读取(Repeatable read),就是一个事物读取时,不允许更新,但允许插入。不会出现不可重复读,但会出现幻读。
4)序列化(Serializable),你麻,只要有事物进行,其他事物必须他妈乖乖等着老子执行完。霸气侧漏,所以不会出现任何并发问题。
以上两个事物会限制读取事物的,所以隔离级别较高,但性能开销不容小觑。
题外话,话说,这几个术语取得真他妈蛋疼,耽误老子理解啊,misleading嘛。
脏读 不可重复读 幻读
Read uncommitted √ √ √
Read committed × √ √
Repeatable read × × √
Serializable × × ×
如何实现事务的隔离级别的
并发控制的有封锁,时间戳, 乐观控制法,多版本并发控制
mysql中不是简单的行级锁,MVCC很多 情况下避免了加锁操作,开销更低
MVCC通过保存数据在某个时间点的快照实现
每行记录后面保存两个隐藏的列实现,一个保存还的创建时间,一个保存行的 删除 ,其实是系统的版本号, 每开始一个事务,系统版本号会自动递增
缺点是需要额外的存储 空间,需要做更多的行检查工作,以及一些额外的维护工作。
MVCC只在Repeatable Read和Read Commited两个隔离级别下工作。
mvcc优缺点:
在读取数据时,innodb几乎不用获取任何锁,在每个查询通过版本检查,只获取需要的数据版本,提高系统并发度
缺点:为了实现多版本,innodb必须对每行增加相应字段来存储版本信息,同时需要维护每一行的版本信息,而且
在检索行的时候,需要进行版本的比较,因而减低了查询效率;innodb还需要定期清理不再需要的行版本,及时回收空间,这也增加开销;
由数据库管理系统实现
使用哪些技术?