A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

1. 定义
所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。
事务最重要就是,四大特性(ACID)和隔离级别

2. 四大特性:原子性、隔离性、一致性、持久性
1. 原子性(atomicity)一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作,这就是事务的原子性。2. 一致性(consistency)数据库总是从一个一致性的状态转换到另一个一致性的状态。例如:银行转账的例子中,一致性确保了,即使在执行第三、四条语句之间时系统崩溃,支票账户中也不会损失200美元,因为事务最终没有提交,所以事务中所做的修改也不会保存到数据库中。)3. 隔离性(isolation)    通常来说,一个事务所做的修改在最终提交以前,对其他事务是不可见的。    例如:在A向B转账的过程中,只要所处事务还没有提交,其他事务查询A或者B账户的时候,两个账户的金额都不会发生变化;        如果在A给B转账的同时,有另外一个事务执行了C给B转账的操作,那么当两个事务都结束的时候,B账户里面的钱应该是A转给B的钱加上C转给B的钱再加上自己原有的钱;4. 持久性(durability)一旦事务提交,则其所做的修改会永久保存到数据库。(此时即使系统崩溃,修改的数据也不会丢失。)               


3. 隔离级别
3-1:不考虑隔离性会出现什么问题?        ---  脏读、不可重复读、幻读
1. 脏读
脏读:一个事务读取到另一个事务未提交的数据的情况被称为脏读。举例说明:    转账的例子。A向B转账,A执行了转账语句,但A还没有提交事务(还没committed),B读取数据,发现自己账户钱变多了!B跟A说,我已经收到钱了。    A此时回滚事务【rollback】,那么原来所有的操作全部回退了,等B再查看账户的钱时,发现钱并没有多。分析:    出现脏读的本质就是因为操作(修改)完该数据就立马释放掉锁,导致读的数据就变成了无用的或者是错误的数据。解决(Read committed):    从上面的分析也能看出来,解决的方式就是把锁释放的位置放到事务提交之后 。这样的话,在事务还未提交之前,其他的事务对该数据是无法进行操作的,这也是Read committed避免脏读的做法;

2. 不可重复度
不可重复读:一个事务中,两次读取的数据的内容不一致。;一个事务读取到另外一个事务已经提交的数据,也就是说一个事务可以看到其他事务所做的修改 ;举例说明:    事务A在读取一条数据,得到结果a,事务B把这条数据改成了b并提交了事务,这个时候事务A再次去读取这条数据,得到的结果是b。这样就发生了不可重复读;    即:A、B同时操作一个数据,当A还在操作,第一次读取是a,当B提交了数据,修改成了b,A此时去读又读的是b。正确的是他应该读到原来的a,等操作完了再和B提交的合并分析:    Read committed 采用的是语句级别的快照!每次读取的都是当前最新的版本!解决:    Repeatable read避免不可重复读是事务级别的快照!每次读取的都是当前事务的版本,即使被修改了,也只会读取当前事务版本的数据。
3. 幻读
幻读/虚读:一个事务中 两次读取的数据的数量不一致 。        是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致 (幻读是事务非独立执行时发生的一种现象);举例说明:    例如事务A对一个表中符合条件的一些数据做了从a修改为b的操作,这时事务B又对这个表中插入了符合A修改条件的一行数据项,而这个数据项的数值还是为a并且提交给数据库。而操作事务A的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务B中添加的,就好像产生幻觉一样,这就是发生了幻读。解决:    但在MySQL实现的Repeatable read配合间隙锁不会出现幻读;    使用间隙锁锁住符合条件的部分,不允许插入符合条件的数据。        

间隙锁
间隙锁:当我们用范围条件检索数据而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合范围条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙(GAP)”。InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁(间隙锁只会在Repeatable read隔离级别下使用)。
InnoDB使用间隙锁的目的有两个:
为了防止幻读
满足恢复和复制的需要
MySQL的恢复机制要求:在一个事务未提交前,其他并发事务不能插入满足其锁定条件的任何记录,也就是不允许出现幻读 ;

所以要考虑隔离性,隔离又存在存在级别。
1. Read uncommitted:未提交读     (读取尚未提交的数据 :哪个问题都不能解决)    最低级别,会出现脏读、不可重复读、幻读。2. Read committed:已提交读       (读取已经提交的数据 :可以解决脏读 ---- oracle默认的)    避免脏读,会出现不可重复读和幻读。3. Repeatable read:可重复读      (重读读取:可以解决脏读 和 不可重复读 ---mysql默认的)    避免脏读和不可重复读,会出现幻读(在MySQL实现的Repeatable read配合gap锁不会出现幻读!)。4. Serializable :串行化          (相当于锁表)    避免脏读、不可重复读、幻读。


事务的基本操作
1. 开启事务()  开启事务后执行修改命令,变更会维护到本地缓存中,而不维护到物理表中    begin; 或者    start transaction;2. 提交事务()    将缓存中的数据变更维护到物理表中    commit    3. 回滚事务()    放弃缓存中变更的数据    rollback





0 个回复

您需要登录后才可以回帖 登录 | 加入黑马