Mysql的innodb也就是默认的msyql数据引擎是支持事务的,Myisam是不支持事务的
什么是事务?事务就是一条或者一组sql语句组成的基本单元,要么全都做,要么全都不做
事务的特性:ACID
原子性:事务不可被拆分,事务中的操作要么全都执行,要么全都不执行
一致性:事务的执行使数据库中的数据从一个一致性状态到另外一个一致性状态
隔离性:事务的执行不会被其它事务打扰
持久性:事务操作对数据库中的数据修改是永久性的
数据库并发访问可能出现的问题:
1.脏读:对于两个事务t1和t2,t1读取了t2更新了但是未提交的数据,若t2回滚,则t1读取的是临时无效的数据
2.不可重复读:对于两个事务t1和t2,t1读取了一个字段,随后t2对该字段进行了更新,t1再次读取该字段时,发现前后读取的结果不一样
3.幻读:对于两个事务t1和t2,t1读取了表中的某个字段,随后t2对该字段进行了插入,随后t1再次读取该字段时发现多出来了几行
事务的隔离级别:(√表示可避免,×表示不可避免)
脏读 不可重复读 幻读
读未提交 × × ×
读已提交 √ × ×
可重复读 √ √ ×
串行化 √ √ √
事务分类:
①隐式事务:没有明显的事务开启或关闭的标志,例如update、delete、insert
②显示事务:事务的开启或关闭有明显的标志
事务开启的语法:
set autocommit=0;
start transaction;(可选)
sql语句;
commint/rollback;
Mysql默认的隔离级别:可重复读
SELECT @@TRANSACTION_ISOLATION;
需要更改Mysql默认的隔离级别的话:
SET GLOBAL TRANSACTION ISOLATION LEVEL 隔离级别;
修改完成后需要重启mysql服务
下面进行一个隔离级别的演示:
1.读未提交的演示:
①将mysql当前会话中事务隔离级别修改为读未提交
②进行数据的查询
③开启另外一个mysql服务,设置隔离级别并对account表中的字段进行一个修改但是未提交
得出结论:读未提交无法避免脏读、不可重复读、幻读
2.读已提交的演示
读已提交避免了脏读的演示:
读已提交避免不了不可重复读和幻读的演示
在一次会话中,前后读取的数据不一样
3.可重复读的演示
可重复读避免了脏读的演示:
可重复读避免了不可重复读的演示:
可重复读避免不了幻读的演示:
在一次事务中,查询出来是两行却更新了三行
4.串行化的演示:
串行化避免了脏读、不可重复读、幻读
加锁等待,直到获得该锁的事务执行完成后才插入成功
虽然串行化避免了脏读、不可重复读、幻读但是由于加锁排队效率偏低,所以一般不采用
savepoint:保存点
案例演示:
SET autocommit=0;
START TRANSACTION;
DELETE FROM account WHERE id=12;
SAVEPOINT a;
DELETE FROM account WHERE id=13;
ROLLBACK TO a;