分享一张最近在学校拍到的照片
事务是什么?
把多个sql语句打包成一个整体,要么全部执行成功,要么一个都不执行,不会出现执行一半的情况
一个都不执行的具体情况就是,在这个过程中,出错了,就会 回滚 (就是恢复原来的状态)
事务的四大特性
1.原子性 2.一致性 3.持久性 4.隔离性
1.原子性
最核心的特性,当时人们认为原子是最小的单位
2.一致性
数据执行前后,要是一致的
3.持久性
事务修改的内容是写在硬盘上的,重启也不会丢失
4.隔离性
为了解决并发执行事务,引起的问题
tips:什么是并发?
服务器同时处理多个客户端的需求
究竟并发会引起什么样的问题呢?
并发修改不同的表和数据肯定问题不大,但是如果修改的是同一个表或者数据就可能会出现问题
比如说多个客户对同一个账户进行转账的操作,就可能会出错
事务并发可能产生的问题
事务并发可能会产生以下三个问题
1.脏读 2.不可重复读 3.幻读
1.脏读
含义:一个事务1 正对数据进行修改,还没有提交呢,事务2就已经读取了,这时事务2的操作就是脏读,读的数据就是脏数据
注意:这里的脏不是说这个数据很脏,而是无效的意思
为什么会无效呢?
因为事务1,还没有提交呢,万一后面事务1,对数据进行了修改,那不是事务2的读取就是无效的
为了解决脏读,我们的办法是 给写“ 加锁 ”,就是在事务1在修改数据的时候,别的事务不能在这时候观看(读取)
2.不可重复读
事务1已经提交数据了,事务2这时在读取,在这过程中,事务1闲不住,又提交了新的数据,这样事务2多次读的数据就不一样了,而我们规定的是读多次都是一样的(简而言之就是第二次读取的结果和第一次读的结果不一样)
为了解决不可重复读,我们采用给 读 “加锁”(在读的时候,别人不能修改)
3.幻读
在写加锁和读加锁的前提下,事务2两次读取的数据值是一样的,但是结果集不一样
(假设在事务2第一次读取student.java数据,事务1因为被加锁了,被迫摸鱼,但是大家都知道事务1是一个闲不住的人,确实事务1对student.Java这个数据加了锁,但是对事务1别的数据又没加锁,于是又去写了另一个数据emp.java,第二次事务2也读取了student.java,确实没变,但是总的结果集里多出了emp.java的数据)
为了解决幻读,我们采用 串行化的方法,彻底放弃并发,一个接一个的串行处理事务
应对上面四种问题,mysql也给出了4种隔离的级别
read uncommitted
没有任何锁的限制,并发性最高(效率最高),隔离性最低(准确性最低)
read committed
给写加锁,并发性降低,隔离性提高
repeatable read
给写和读加锁,并发性再降低,隔离性再提高
serializable
串行化,并发性最低(效率最低),隔离性最高(准确性最高)
根据具体情况使用合适的限制,比如说,涉及金钱交易的,当然最好选择串行化,虽然效率很低,但是很准确