1、事务的概念
事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败。 在不同的环境中,都可以有事务。对应在数据库中,就是数据库事务。
把多个操作打包成一个整体,要么全部都执行完,要么一个都不执行(原子性),这是事务最核心的特性。
执行出错,自动恢复成执行前的样子,这样的逆操作叫做 “回滚”(rollback)
回滚就是把执行过的操作逆向恢复回去,(数据库会记录每个操作,如果某个操作出错就会回滚)
2、使用
(1)开启事务:start transaction;
(2)执行多条SQL语句
(3)回滚或提交:rollback/commit;
说明:rollback即是全部失败,commit即是全部成功。
开启事务后,中间的sql不会立即就执行,而是先攒着,等commit再统一执行(保证原子性)
start transaction;
-- 阿里巴巴账户减少2000
update accout set money=money-2000 where name = '阿里巴巴';
-- 四十大盗账户增加2000
update accout set money=money+2000 where name = '四十大盗';
commit;
3、事务核心特性
- 原子性 (事务的初心)
- 一致性 事务执行前执行后都得是数据合法的状态
- 持久性(硬盘) 事务产生的修改都是会写入硬盘的,即使程序重启,事务也可以正常工作
- 隔离性 一个数据库服务器同时执行多个事务时,事务之间的“相互影响程度”
关于隔离性:
mysql服务器要同时给多个客户提供服务,此时多个客户端之间可能会同时发起事务,尤其是这多个事务在操作同一个数据库的同一张表,这个时候就会出问题。
隔离性越高,事务之间并发程度越低,执行效率越慢,数据准确性越高(算钱)
隔离性越低,事务之间并发程度越高,执行效率越快,数据准确性越低(点赞数)
4、脏读问题(dirty data)
事务之间完全并发,没有任何限制,就会出现脏读问题
解决办法:降低事务的并发性,提高隔离性(俗称“加锁”)
加锁:事务B写数据的时候,事务A停止读数据;事务A读数据的时候,事务B停止写数据
5、幻读问题
在同一个事务中两次读到的结果集不同,
解决办法:串行化,彻底舍弃并发
事务B写数据的时候,事务A停止任何操作
6、隔离级别
- read uncommitted:不做任何限制,事物之间随意并发执行,并发程度最高,隔离性最低,会产生脏读+幻读+不可重复读问题
- read committed:对写操作加锁,并发程度降低,隔离性提高,解决脏读问题,依旧存在幻读+不可重复读的问题
- repeatable read(默认):对写操作和读操作都加了锁,并发程度再次降低,隔离性又提高,解决脏读+不可重复读问题,可能存在幻读的问题
- serializable:严格串行化,并发程度最低,隔离性最高,可以解决脏读+幻读+不可重复读的问题