一个事务transaction就是一个完整的业务逻辑,一个最小的工作单元,不可再分(转账)。说到底,本质上事务就是多条DML语句同时成功或者同时失败!
只有DML数据库操纵语言(insert update delete)语句才有事务一说,其它语句与事务无关。数据安全是第一位!!!
正是因为做某件事需要多条DML语句共同联合起来才能完成,所以需要事务的存在。
InnoDB引擎提供一组用来记录事务性活动的日志文件。
commit提交事务:清空事务活动日志文件,将数据全部彻底持久化到数据库,标志着事务的结束-全部成功;
rollback回滚事务:将之前所有DML操作全部撤销并清空事务活动的日志文件,标志的事务的结束-全部失败。(只能回滚到上一次的已提交点)
mysql默认支持自动提交事务(不符合开发习惯,为保证安全最好一组DML语句后提交),每执行一条DML语句就提交。start transaction; 关闭自动提交。
事务四特性ACID
A:Atomicity原子性:说明事务作为一个整体被执行,是最小的工作单元,不可再分。
C:Consistency一致性:事务开始前和结束后不管成功与否,数据不被破坏、总数不变。
I:Isolation隔离性:A和B事务并发访问同一张表时相互隔离不影响对方运行(一道墙)。
D:Durability持久性:事务结束的保障,事务提交相当于将数据持久保存到硬盘。
重点研究事务的隔离性:
隔离级别:A教室与B教室之间的一道墙越厚则隔离级别越高。
事务与事务之间(两个终端(两个进程)登录同一个数据库开启各自的事务)的4个隔离级别:
读未提交:read uncommited,事务A可以读取到事务B未提交的数据。这在最低隔离级别存在脏读现象,读到了脏数据。这是理论上的一般不用,大多数据库隔离级别都是二档起步!(没有提交就读到了)
读已提交:read commited,事务A只能读取到事务B提交之后的数据,解决了脏读现象。存在问题:不可重复读取数据。在事务开启后,第一次读到3条数据,当事务不断提交还未结束,可能第二次再读取的时候读到4条数据,3不等于4。这种隔离级别是比较真实的数据,这是oracle默认的隔离级别。(提交之后才能读到)
可重复读:repeatable commited,事务A开启之后,不管什么时候,每一次在事务A中读取的数据都是一致的,即使事务B将数据已经修改并提交,事务A读取到的数据不会改变。存在问题:可能会出现幻影读,每一次读取到的数据都是幻象,不够真实。这是mysql的默认隔离级别。(B提交后也读不到,永远读取的是刚开始开启事务时的数据-快照/备份数据,除非A提交)
序列化/串行化:serializable,最高隔离级别-最严格解决所有问题,表示事务排队,不能并发,B要操作必须等A提交。有点类似于线程同步(事务同步),事务的访问权有先后顺序,每一次读取真实数据,但效率最低。
查看隔离级别:select @@tx_isolation;
设置全局隔离级别:set global transaction isolation level read uncommited;
脏读:事务A读到了事务B还未提交的数据
不可重复度:在一个事务里两次读取了某个数据,读出的数据不一样
幻读:事务A读取的一直是事务开始时的数据,事务B删除或插入新数据后事务A不知道