1、事务的特性
如果一个数据库声称支持事务的操作,那么该数据必须具备以下四个特性:
原子性、一致性、隔离性、持久性
原子性(Atomicity)
一次事务中如果进行多个数据操作的业务,最终的结果要么所有操作都成功,要么所有操作都失败
DEMO:转账
A转账给B,转了1000元,最终的结果要求:A的账户减少1000元,B的账户增加1000元,不能出现A账户减少了,但是B没有增加
一致性(Consistency)
一致性就是数据表的数据更新要求合乎逻辑的特性,满足了原子性不一定满足一致性。
DEMO:转账
A转账给B1000元,最终结果:A账户减少1000元,但B账户增加100元,此时事务是满足原子性的,但是不合乎逻辑,就不满足事务的一致性了
隔离性(Isolation)
隔离性是当多个用户并发访问数据库时,此时同时操作一条数据,数据库为每一个用户开启的事务(为该数据上锁,其它事务在上一个事务操作完毕之前是不能操作该数据的),不能被其它事务的操作所干扰,多个并发事务之间要互相隔离
持久性(Durability)
持久性是指一个事务一旦被提交(COMMIT)了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
以上简称事务的四大特性(简称ACID),重点来了解下事务的隔离性,当多个线程(多个用户或者多个事务)都开启事务操作数据库中的数据时,数据库系统要能进行隔离操作,以保证各个事务获取数据的准确性,事务如果没有隔离性会发生以下几个问题:
更新丢失
如果多个用户操作数据,基于同一个查询结果对表中的记录进行修改,那么后面修改的记录将会覆盖前面修改的记录,前面的修改就丢掉了,这就叫做更新丢失。这是因为系统没有执行任何的锁操作(没有隔离性),因此并发事务并没有被隔离开来
第1类丢失更新:事务A撤销时,都已经提交的事务B的更新数据覆盖了
第2类丢失更新:事务A覆盖事务B已经读取了另外一个事务未提交的数据(即将回滚的数据)
解决办法:如果在操作事务完成数据处理之前,任何其他事务都不可以添加数据,则可避免该问题
脏读
脏读是指在一个事务处理过程中读取了另外一个事务未提交的数据或者说是回滚的数据
解决办法:如果在第一个事务提交前,任何其他事务不可读取其修改过的值,则可以避免该问题
不可重复读
一个事务对同一行数据重复读取两次,但是却得到了不同的结果,事务T1读取某一数据后,事务T2对其做了修改,当事务T1再次读该数据时得到与第一次不同的值
解决办法:如果只有在修改事务完全提交之后才可以读取数据,则可以避免该问题
不可重复和脏读的区别:
脏读是某一事务读取了另外一个事务未提交的脏数据(即将回滚的数据)。而不可重复读则是读取了前一事务提交(更新)的数据
在某些情况下,不可重复读并不是问题,比如我们多次查询某个数据当然以最后查询得到的结果为主
虚读(幻读)
同一个事务中两次统计一张数据表的数据得到的结果不一致,第二次读会增加一行数据,例如:A事务第一次统计了所有员工的薪资之和为10000,但是事务还没有结束,因为还要读取第二次,但是在此期间事务B向表中增加了一条员工信息,并且薪资是1000,此时事务A第二次再去统计薪资结果是:11000,最终事务A两次统计的结果不一致,这就叫做虚读
解决办法:如果在操作事务完成数据处理之前,任何其他事务都不可以添加数据,则可避免该问题
不可重复读和幻读的区别:
不可重复读:描述的是一个事务两次读取同一条数据,发现两次读取的数据结果不一致
幻读(虚读):描述的也是一个事务两次统计某张数据表的时候,发现最终统计结果不一致