事务,ACID,隔离级别
<1>.事务的概念:
事务是用户定义的一个数据库操作序列,是数据库的逻辑操作单位。这些操作要么全做,要么全不做,是一个不可分割的工作单位。事务和程序是两个概念。一般来说,一个程序中包含多个事务。
<2>. 事务的四个特性ACID:
- 原子性A(Atomicity),事务是数据库的逻辑操作单位。这些操作要么全做,要么全不做。银行转账过程中出现错误,整个事务将回滚。只有事务中的所有部分都成功执行了,才将事务写入磁盘并使变化永久化。
-
一致性C(Consistency),事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。
一致性与原子性是密切相关的。且两者从概念上容易混淆,我对一致性的理解是,数据库的数据状态符合数据库所描述的业务逻辑和规则。例如以下代码
read(A);
A = A – 100;
write(A);
read(B);
B = B + 100;
write(B);
如果该事务成功执行,没有任何问题。假如执行到read(B)发生了错误,如果没有原子性要求,那么银行系统就会凭空消失100,这也导致了数据库不一致。
但是数据库的不一致不一定是由原子性的破坏造成的,例如:
read(A);
A = A – 100;
write(A);
read(B);
B = B + 50;
write(B);
虽然该事务正常执行,也满足原子性的要求,但是却不满足一致性要求。
所以说原子性的破坏可能导致数据库不一致,但并非是必要条件。因此,事务的原子性与一致性缺一不可。(保证数据库一致性的责任落在了程序员身上。)
- 隔离性I(Isolation),一个事务的执行不能被其他事务干扰。即一个事务内部的操作对并发的其它事务来说是隔离的,并发执行的各个事务之间不能相互干扰。如果有另一个过程根据帐户余额进行相应处理,而它在我们的事务完成前就能看到它造成的变化,那么这个过程的决策可能建立在错误的数据上。
- 持续性D(Durability),事务一旦提交,它对数据库中数据的改变就是永久性的。接下来的其它操作不应该对其执行结果有任何影响。应该存在一些检查点防止在系统失败时丢失信息。甚至硬件本身失败,系统的状态仍能通过在日志中记录事务完成的任务进行重建。持久性的概念允许开发者认为不管系统以后发生了什么变化,完成的事务是系统永久的部分。
<3>.隔离性的四个级别:
有个分析的很好的讲解文章,出自美团点评技术团队:
http://tech.meituan.com/innodb-lock.html
这里做一些简单的说明,以供快速回忆起相关知识
先介绍三种不同的一个事务读取另外一个事务可能修改的数据的“读现象”。
脏读,一个事务允许读取另外一个事务修改但未提交的数据时,脏读就可能发生。
不可重复读,在一次事务中,当一行数据获取两遍得到不同的结果表示发生了“不可重复读”。
2.PNG在这个例子中,事务2提交成功,因此他对id为1的行的修改就对其他事务可见了。但是事务1在此前已经从这行读到了另外一个“age”的值。在可序列化(SERIALIZABLE)和可重复读的隔离级别,数据库在第二次SELECT请求的时候应该返回事务2更新之前的值。在提交读和未提交读,返回的是更新之后的值,这个现象就是不可重复读。
幻影读,在事务执行过程中,当两个完全相同的查询语句执行得到不同的结果集。
3.PNG“幻影读”是不可重复读的一种特殊场景:当事务1两次执行SELECT ... WHERE检索一定范围内数据的操作中间,事务2在这个表中创建了(如INSERT)了一行新数据,这条新数据正好满足事务1的“WHERE”子句。
事务的四种隔离级别