MySQL事务(transaction)(笔记)
事务(Transaction)(必须掌握必须理解)
1.什么是事务?
一个事务是一个完整的业务逻辑单元(一个业务逻辑单元常常涉及到多条DML语句共同执行完成),不可再分(最小的工作单元)
一个事务就是一个业务,完成一个业务需要使用多条DML语句完成,但是在操作数据的
过程中,为了保障数据的安全性,我们需要采用"事务"这种机制.
比如转账:
要想保证以上DML语句同时成功或者同时失败,就需要使用数据库的'事务机制'
2.和事务有关的语句只有: DML语句.(insert delete update),这三个是针对数据库表中的数据进行增删改
只要涉及到数据的增删改就一定要考虑安全问题
3.事务的原理
开启事务后,那么你所执行的多条DML语句在还没提交或者之前都不会真正的修改硬盘上的数据,只是记录在缓存
4.事务包括四大特性:ACID
(java中可以两个线程操作数据库,那就是两个事务)(A教室和B教室隔一道墙)
(是事务成功的一个保证,如果缓存中记录没有被清除,那这个事情就一直没结束..)
一个事务就是一个业务正在进行中...为了保证这个业务能够完整,无损的,从头执行到尾,我们需要借助事务.没有事务无法保证数据的安全..
5.事务之间的隔离性(隔离级别 :A教室和B教室中间的这道墙可以很厚也可以很强,这道墙越厚,表示级别就越高).
事务隔离性存在隔离级别,理论上隔离级别包括4个:(所有数据库都是默认2级别起步)
第一级别:读 未提交(read uncommitted)(最低的隔离级别)
(一)事务A可以读取到事务B的未提交的数据(一般从二挡起步)
(二)对方事务还没有提交,我们当前事务可以读取到对方未提交的数据.
(三)读未提交存在脏读(Dirty Read)现象: 表示读到了脏(不稳定的)的数据
(四)这种隔离级别一般都是理论上的
第二级别:读 已提交(read committed)
(一)这种隔离级别解决了: 脏读现象.(事务A只能读取到B提交后的数据)
(二)对方事务提交之后的数据我方可以读取到.
(三)读已提交 存在的问题是:不可重复读(开启事务后,第一次读到的数据是三条,可能第二次再读到的时候,可能是四条,这种数据绝对真实)(做不到我这个事务从头到尾查询结构都是一样的)
第三级别:可重复读(repeatable read)
(一)事务A开启之后,不管是多久,第一次在事务中读到的数据都是一致的,即使事务B数据已经修改,并且提交了,事务A读到的数据还是没有发生改变
(二)幻读:前后读到的行数不一致,读id=1时数据查不出来,但是插入的时候发现重复了,(事务一在执行查询操作的时候,id=1查不出来,但是这时候事务二插入了id=1这条数据,这时候事务一也打算插入发现报错了,可能报主键重复问题了。事务一不敢相信地又查了一下,根本就没有这条id=1的记录)出现了幻读现象
(三)这种隔离级别解决了: 不可重复读问题.
(四)你提交之后的数据我读不到,我读到的永远都是我开启事务的时候的数据...(前提是事务只要没结束..窗口只要没关...我读到的数据一直都是我开启事务的时候的数据),所以插入数据的时候又发现这行数据已经存在了!
(五)这种隔离级别存在的问题是: 读取到的数据是幻象(不够绝对真实).(实际上读的是备份数据,硬盘上数据其实已经被改了)(比方说,银行总账,它需要执行select语句,从下午一点开始,到下午五点才能结束,这中间有人会存款取款,那么我们要在几档级别,就是说只存款取款不更新)
第四级别:序列化读/串行化读 serializable.
(一)解决了所有问题
(二)效率低.需要事务排队.我一个事务没结束,其他事务休想开启.(并且不能并发)
如果A没有点commit 那么B永远都得卡着等待,如果A一提交那么B从一直卡着等直接操作出来了
补充:
幻读问题的解决方案:
(1) 串行化读
(2) 插入数据之前,加行级锁读..如果加行级锁为空,表示可以插入,如果行级锁不为空,说明不能插入.解决了幻读的时候插入数据时重复的现象!!!