事务的基本概念
事务是数据库里面的一个基本概念。
所谓事务,就是一系列的数据库操作
。注意是一系列的操作,这些操作要么全做,要么一个也不做,这是一个不能被分割
的单位。事务处理可以维护数据库的完整性。
在关系数据库中,一个事务可以是:
- 一条SQL语句
- 一组SQL语句
- 整个程序
事务和程序是两个概念。一般来讲,一个程序中往往会包含多个事务。
在SQL
中,定义事务的语句一般有三条:
- BEGIN TRANSACTION;
- COMMIT;
- ROLLBACK;
在MySQL
中,是如下三条:
- START TRANSACTION;
- COMMIT;
- ROLLBACK;
事务往往是从BEGIN TRANSACTION
开始,以COMMIT
或者ROLLBACK
结束。
COMMIT
代表提交操作,即提交事务的所有操作,也就是说将事务中那些对数据库的更新同步写到磁盘上去。对于一般的SQL
语句来讲,都是直接针对数据库表执行和编写的,也就是说SQL语句执行后会自动同步更新到磁盘上,这也被称为隐含提交(implicit commit)
,而在事务中,提交不会自动完成,为了进行明确的提交,需要使用COMMIT
语句。
ROLLBACK
代表回滚操作,即在事务的执行过程中如果遇到问题,不能够正常执行下去,那么就回滚到事务执行前的状态。这也就体现了事务的原子性
:要么全部执行,要么全不
执行。
事务的特性
事务具有4个特性:
- 原子性(Atomicity):原子性就是说明事务中包括的那些所有操作,要么都做,要么都不做,省的发生问题。
- 一致性(Consistency):这个一致性的意思是如果执行一个事务,那么事务执行之前和执行之后必须是从一个一致性状态转变到另一个一致性状态。那什么是一致性状态?举个例子,假如小明从银行卡转了1000元钱到支付宝,简单抽象为两个操作,将银行数据库中小明的余额减少1000,然后将支付宝数据库中小明的余额增加1000。这是两个操作,但是一个事务。如果转钱成功,那么就从一个一致性状态转移到了另一个一致性状态,是没有问题的。而如果银行那边少了1000元,支付宝这边却没有加上1000,那就不一致了,就遇到了问题。这就是一种不正确的状态,此时就需要
ROLLBACK回滚
,回滚到银行那边没有减钱时的状态。 - 隔离性(Isolation):一个事务的执行不能被其他事务干扰。也就是说一个事务的内部操作及使用的数据对其他并发事务是隔离的,互不影响。
- 持续性(Durability):持续性指的是,一个事务一旦提交,它对数据库中的数据改变就是持续性或者永久性的。接下来的其他操作或者故障不应该对这个执行结果有影响。比如你转了1000元到了支付宝,就应该立马可以使用支付宝花出去了。
这四个特性简称为ACID特性(ACID properties)
事务管理的重要任务就是指保证事务的ACID
特性。因为事务的这四大特性也会可能遭到破坏的,例如:
- 多个事务并行运行时,不同事务的操作交叉执行。当然,不同事务的操作可以交叉执行,但是不能影响事务的原子性。不能说一个事务正在执行,而同时有其他事务对这个事务造成了一些影响,导致这个事务只执行了一半。
- 事务在执行过程中遇到不可抗力被强行停止。比如正在往数据库写入数据,突然断电了,数据只写了一半,事务被强行停止。
遇到如上的情况时候,就需要对数据进行恢复了,将数据库恢复到正确的状态。
数据库恢复
在实际应用中,数据库可能会出现各种各样的问题,有可能数据库本身遭到破坏,也有可能数据库没有受到破坏,但是数据出现不正确。当出现这些问题的时候,我们肯定需要将数据库恢复到正常,能够正常使用,而实际上,数据库恢复的基本原理很简单,用一个词就能概括:冗余
。也就是建立冗余数据,说的好听点就是搞一点正常情况下多余的数据,用来帮助恢复数据库。比如对数据库直接进行备份
,那么如果数据库遇到问题,直接把备份数据加载使用就行。或者登记一些日志文件
,这些日志文件记录进行的操作、遇到的问题等。恢复的时候通过分析日志文件进行数据库恢复。
在实际数据库系统中,这两种方法往往是一起使用的。
其中对数据进行备份也叫做数据转储
,数据转储是数据库恢复中采用的基本技术,也就是数据库管理员定期的将整个数据库的数据复制到硬盘等存储介质上保存起来的过程,这些备用的数据也叫做副本。
但是这些数据库恢复方法都只能将数据库恢复到故障发生前的某一个确定状态。
当数据库遭到破坏的时候,可以将后备副本重新装入数据库使用,但是重装后只能将数据库恢复到存储时的状态
,要想恢复到故障发生时的状态,必须重新运行自转储
以后的所有更新事务,这个时候就会结合日志文件。
因为在很多企业等,数据量都是十分庞大的,因此转储是十分耗费时间和资源的,不能频繁的进行。因此需要确定适当的转储周期。
而转储分为静态转储
和动态转储
。
静态转储比较好理解,就是在系统没有运行任何事务的时候,对数据进行转储。即转储操作开始的时候数据库处于一致性状态。同时转储期间不允许对数据库进行任何存取修改活动。
动态转储就是指转储期间允许对数据库进行存取和修改。即转储和用户事务可以并发执行。但是动态转储后的数据不一定能保证正确有效,因此在动态转储的时候,需要建立执行的各事务对数据库的修改活动的日志文件。这样转储成功后可以结合日志文件将数据库恢复到某一时刻的正确状态。
同时数据转储又有两种方式,为海量转储
和增量转储
。前者指直接备份数据库的所有数据,后者指只更新改变的数据。