1、事务概念:
一组sql语句操作单元,组内所有SQL语句完成一个业务,如果整组成功:意味着全部SQL都实现;如果其中任何一个失败,意味着整个操作都失败。失败,意味着整个过程都是没有意义的。应该是数据库回到操作前的初始状态。这种特性,就叫“事务”。
2、为什么要存在事务?
1)失败后,可以回到开始位置
2)没都成功之前,别的用户(进程,会话)是不能看到操作内的数据修改的
3、事务4大特征ACID:
1. 原子性[atomicity]
功能不可再分,要么全部成功,要么全部失败
2. 一致性[consistency]
一致性是指数据处于一种语义上的有意义且正确的状态。一致性是对数据可见性的约束,保证在一个事务中的多次操作的数据中间状态对其他事务不可见的。因为这些中间状态,是一个过渡状态,与事务的开始状态和事务的结束状态是不一致的。
举个例子,张三给李四转账100元。事务要做的是从张三账户上减掉100元,李四账户上加上100元。一致性的含义是其他事务要么看到张三还没有给李四转账的状态,要么张三已经成功转账给李四的状态,而对于张三少了100元,李四还没加上100元这个中间状态是不可见的。
我们来看一下转账过程中可能存在的状态:
- 张三未扣减、李四未收到
- 张三已扣减、李四未收到
- 张三已扣减,李四已收到
** **上述过程中: 1. 是初始状态、2是中间状态、3是最终状态,1和3是我们期待的状态,但是2这种状态却不是我们期待出现的状态。 - 锁
那么反驳的声音来了:
要么转账操作全部成功,要么全部失败,这是原子性。从例子上看全部成功,那么一致性就是原子性的一部分咯,为什么还要单独说一致性和原子性?
你说的不对。在未提交读的隔离级别下是事务内部操作是可见的,明显违背了一致性,怎么解释?
好吧,需要注意的是:
原子性和一致性的的侧重点不同:原子性关注状态,要么全部成功,要么全部失败,不存在部分成功的状态。而一致性关注数据的可见性,中间状态的数据对外部不可见,只有最初状态和最终状态的数据对外可见
3. 隔离性[isolation]
事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。
隔离性是多个事务的时候, 相互不能干扰,一致性是要保证操作前和操作后数据或者数据结构的一致性,而我提到的事务的一致性是关注数据的中间状态,也就是一致性需要监视中间状态的数据,如果有变化,即刻回滚
如果不考虑隔离性,事务存在3种并发访问数据问题,也就是事务里面的脏读、不可重复读、虚度/幻读
mysql的隔离级别:读未提交、读已提交、可重复读、串行化
4. 持久性[durability]
是事务的保证,事务终结的标志(内存的数据持久到硬盘文件中)
4. 分布式事务
分布式事务顾名思义就是要在分布式系统中实现事务,它其实是由多个本地事务组合而成。
对于分布式事务而言几乎满足不了 ACID,其实对于单机事务而言大部分情况下也没有满足 ACID,不然怎么会有四种隔离级别呢?所以更别说分布在不同数据库或者不同应用上的分布式事务了。