课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
事务是程序员在学习数据库编程开发技术的时候需要重点掌握的编程知识之一,而ACID是事务的基本特性,下面我们就通过案例分析来了解一下程序员如何理解数据库事务特性。
原子性
如何理解原子性呢?在化学中,物质都是由原子构造,早期的化学家有一个想法,将物质进行切分,就像切蚯蚓一样。但是不管怎么切,每次都会变得更小。那么切到什么程度就不能切了呢?后认为原子是小的单位,即不能再进行分割。因此原原子表示不可分割,其实原子还是可以分割为自由电子和原子核。原子性可以理解为“不可分割”,原子核和自由电子是不可分割的一个整体。
套用在数据库系统中,原子性就是组成事务的读写操作指令的集合是一个整体,不可分割。这些事务单元的一系列操作命令,要么全部执行,要么全部不执行(回滚)。
宏观上来看,事务要么成功,要么就是失败,不能有其他状态。例如Bob给Smith转账的case中,只有两种结果,转账成功(Bob账户少100,Smith账户多100),或者转账失败(权当事务没有发生过)。不能存在,Bob转出去了,而Smith账户却没有收到钱的中间状态。
因为操作指令不能分割,就不存在有的指令执行成功,有的未执行或执行失败的中间状态。
这里的原子性强调的是从事务单元的宏观角度来看,事务成功或者失败。微观上来看就是事务可以恢复,恢复到事务尚未发生的状态。
一致性
一致性也是一个颇为让人费解的定义。顾名思义,一致性强调的就是一样。CAP理论也有一致性,在分布式系统中一致性只各个节点的数据都一样。数据库的一致性含义却是数据库从一个正确的状态,转变成另外一个正确的状态,这里更多的强调是正确性,更像是业务要求,业务又属于应用层软件所要关系的特性,数据库此时的角色略显尴尬。
之所以会有不一致,原因就是数据库在执行事务单元的时候是并发操作。即事务单元的指令是相互交叉并发执行,如果执行顺序不对,会有可能带来业务属性的错误。导致事务执行结束之后,发现数据库是不一致的(错的)。
如果是串行的执行,那么肯定就不会有一致性问题。因此一致性也可以这么理解,就是并发执行的事务,其结果和串行执行的结果一致(正确),那么就说这个并发事务符合一致性。
隔离性
串行执行数据库事务读写操作时,一定会保证数据库的一致性。然而很多时候,不同的线程的读写操作的未必是同样的数据。Bob在给Smith转账的时候,Tom也可能给Green转账。他们两个事务完全可以并行执行,相互之间不受影响。因此我们可以并发调度这两个事务进行,宏观上看他们就是同时进行的。隔离性就是指并发调度的事务,相互之间没有影响,事务都任务只有自己在执行。
隔离性的本来要求一组对数据库的并发修改互相不影响,可是实际上,像上面不操作同样数据的时候就不会有影响,而操作相同数据元素的时候,就可能产生冲突,冲突就会导致不一致。因此就需要区分哪个修改优先级更加高,而高优先级的修改应该覆盖掉低优先级的修改。
持久性
数据库系统后一个特性是持久性,这也是一个字面意思很好理解的特性。持久性指的就是事务提交之后,就一定是在硬盘永久的存储,而不会丢失。虽然持久性比较好理解,可是实现却不简单,数据库系统通过undo,redo,undo/redo日志实现。即对数据库硬盘存储数据的时候,都是先写日志,再写存储。
通常,软件对数据的操作都在内存,内存数据是易丢失的。存储多数在外存(硬盘)。一个事务的提交操作包括内存和硬盘之间的交互。
事务的处理在内存里进行,当事务进行提交的时候,实际上是把数据写入到内存的DB缓冲区了,然后再将DBbuffer的数据强制写入硬盘中。DBbuffer到disk之间的交互用output指令表示。对于不同的日志类型,Commit和output的先后顺序也不一样。
Undo日志是在写了commit之后,再进行output操作,redo日志则相反,再进行output操作,再写入commit日志。当数数据库发生故障的时候,需要根据日志的规则进行事务的撤销和重做,保证在commit之后,数据一定要落盘。具体的原理和过程将会在故障处理的部分进行讨论。
【免责声明】:本内容转载于网络,转载目的在于传递信息。文章内容为作者个人意见,本平台对文中陈述、观点保持中立,不对所包含内容的准确性、可靠性与完整性提供形式地保证。请读者仅作参考。更多内容请在707945861群中学习了解。