事务
1 什么是事务?
事务,一般指要做的或所做的事情,在计算机术语中是指访问并可能更新数据库中各项数据的一个程序执行最小单元。事务通常由高级数据库操纵语言或编程语言(eg:sql,java)书写的用户程序所引起,并用形如begin transaction和end transaction语句(或函数调用)来界定。事务由事务开始和事务结束之间执行的全体操作组成。
为什么需要事务?
-
事务就是为了解决数据安全操作提出的,事务控制实际上就是控制数据的安全访问。
举一个简单的例子:
-
我们在微信进行转账操作,要将账户A的200员转到B账户下面,A账户首先要减去200元,然后B账户要增加200元,但是如果在中间出现网络异常或者其它问题,这时A账户已经减了200元,而B账户却并没有增加200元,那么整个操作就是失败的,必须要做出控制,要撤销A账户转账操作,这才能保证业务的正确性,要正确的完成整个操作流程,就需要引入事务,将A账户资金减少和B账户资金增加放入一个事务中,只有所有的操作都成功,才进行提交,这样就保证了数据的安全性。
2 事务的4个特性(ACID)
1) 原子性(atomicity):事务是数据库的逻辑工作单位,而且是必须是原子工作单位,对于其数据修改,要么全部执行,要么全部不执行。
2) 一致性(consistency):事务在完成时,必须是所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。(实例:转账,两个账户余额相加,值不变。)
3) 隔离性(isolation):一个事务的执行不能被其他事务所影响。
4) 持久性(durability):一个事务一旦提交,事物的操作便永久性的保存在DB中。即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
3 脏读、不可重复读、幻读
脏读
- 脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。
- 比如在事务 A 修改数据之后提交数据之前,这时另一个事务 B 来读取数据,如果不加控制,事务 B 读取到 A 修改过数据,之后 A 又对数据做了修改再提交,则 B 读到的数据是脏数据,此过程称为脏读。
不可重复读
- 不可重复读是指在数据库访问中,一个事务范围内多次查询却返回了不同的数据值。这是由于在查询间隔中,其他事务修改并提交而引起的。
- 比如事务 T1 读取某一数据,事务 T2 读取并修改了该数据,T1 为了对读取值进行检验而再次读取该数据,便得到了不同的结果。
幻读
- 幻读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,比如这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。
- 比如事务 A 在按查询条件读取某个范围的记录时,事务 B 又在该范围内插入了新的满足条件的记录,当事务 A 再次按条件查询记录时,会产生新的满足条件的记录。
4 SQL的四个隔离级别
未提交读(Read Uncommitted)
- 一个事务能够读取到别的事务中没有提交的更新数据。事务中的修改,即使没有提交,其他事务也可以看得到。在这种隔离级别下有可能发生脏读,不可重复读和幻读。
提交读(Read Committed)
- 事务中的修改只有提交以后才能被其它事务看到。在这种隔离级别下解决了脏读,但是有可能发生不可重复读和幻读。
可重复读(Repeated Read)
- 保证了在同一事务中先后执行的多次查询将返回同一结果,看到的每行的记录的结果是一致的,不受其他事务的影响。但是这种级别下有可能发生幻读。
可串行化(Serializable)
- 不允许事务并发执行,强制事务串行执行。就是在读取的每一行数据上都加上了锁,读写相互都会阻塞,所以效率很低下。这种隔离级别最高,是最安全的,但是性能最低,不会出现脏读,不可重复读,幻读。