什么是事务?
事务(Transaction)是并发控制单位,使用户定义的一个操作序列,这些操作要么都做,要么都做,不存在部分做部分不做的情况,是一个不可分割的工作单位。
事务通常以BEGIN TRANSACTION开始,以COMMIT或ROLLBACK结束。
想象一下你给Gavin转账100元(真金白银)的场景。从数据层面来看,其实就是在你的账号-100元,同时在Gavin的账号上面+100元,这不难理解。但是会不会出现某种特殊情况,导致Gavin的账号+100失败了,但是你的账号-100成功了。怎么办?此时我们需要一种解决方案,使的要么两个账户都操作,要么两个账户都别操作。工作中我们经常会遇到类似的情况,所以当我们要进行多表操作的时候,就要考虑到数据库的事务了。
事务的四大特性ACID
1.原子性(Atomicity)
一般来说,原子是指最小单位。这里指系统只能处于操作之前或操作之后的状态,而不是介于两者之间的状态。
ACID原子性的定义特征是:能够在错误时中止事务,丢弃该事务进行的所有写入变更的能力。
2.一致性(Consistency)
一致性就是说,事务必须使数据库从一个一致的状态转换到另一个一致的状态。也就是说一个事务在执行前和执行后都必须处于一个一致性的状态。
举个栗子,假设Gavin和Carrie的钱加起来一共是500,那么不管他们之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是500,这就是事务的一致性。
3.隔离性(Isolation)
大多数数据库都会同时被多个客户端访问。如果它们各自读写数据库的不同部分,这是没有问题的,但是如果它们访问相同的数据库记录,则可能会遇到并发问题(竞争条件(race conditions))。 ACID意义上的隔离性意味着,同时执行的事务是相互隔离的:它们不能相互冒犯。
如果两个事务不触及相同的数据,它们可以安全地并行(parallel) 运行,因为两者都不依赖于另一个。当一个事务读取由另一个事务同时修改的数据时,或者当两个事务试图同时修改相同的数据时,并发问题(竞争条件)才会出现。出于这个原因,数据库一直试图通过提供事务隔离(transaction isolation) 来隐藏应用程序开发者的并发问题。
serializable级别的隔离,保证事务的效果与连续运行(即一次一个,没有任何并发)是一样的,可以保证事务地安全执行。但是在serializable隔离级别,事务并发度很低,整个数据库的性能肯定不高。这时候,数据库开发人员有提出了四种不同的隔离级别,来平衡事务并发度与隔离性,这四个隔离级别分别是:
·读未提交(Read Uncommitted):可以读取未提交的记录。
·读已提交(Read Committed):事务中只能看到已提交的修改。
·可重复读(Repeatable Read):解决了不可重复读问题(MySQL 默认隔离级别)
·序列化(Serializable):最高隔离级别。
RU,RC和RR由于降低了隔离要求,自然在读取数据时,可能会产生各种异常:
RU会读取其他事务未提交的数据,这就产生了脏读,脏读意味着另一个事务可能会只看到一部分更新,或者看到的数据已经被回滚了。
RC级别的隔离,会产生不可重复读的问题。所谓不可重复读是指在一个事务内根据同一个条件对行记录进行多次查询,但是搜出来的结果却不一致。发生不可重复读的原因是在多次搜索期间查询条件覆盖的数据被其他事务修改了。
RR级别的隔离,会产生幻读问题。幻读,并不是说两次读取获取的结果集不同,幻读侧重的方面是某一次的 select 操作得到的结果所表征的数据状态无法支撑后续的业务操作。更为具体一些:select 某记录是否存在,不存在,准备插入此记录,但执行 insert 时发现此记录已存在,无法插入,此时就发生了幻读。
4.持久性(Durability)
持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变是永久的,即便实在数据库系统遇到故障的请胯下也不会丢失提交事务的操作。为我们提供了一个安全的地方存贮出具,而不用担心丢失。
网友评论