介绍mysql事务之前,先介绍目前的数据库发展情况,就目前2019/03/29之前的版本(已经到8.0.X),支持事务的依旧是InnoDB存储引擎,现在默认的一个存储引擎,再5.5之前是myisam作为默认存储引擎
Q 单线程运行速度怎么样? | A 很快 |
Q 那我要是同一时间有2个人需要执行,单线程能做吗? | A 能做,但是同一时间只会有一个人有执行的权力,另外一个人会阻塞 |
Q 现在的CPU都是多核 超核,能够支持多线程,能够提速吗? | A 当然可以,但是会有一个问题,对于临界资源的操作,会出现数据不一 致问题 |
Q 怎么解决数据一致性的问题呢? | A 通过加锁来解决,但是数据库中有2中锁,表级锁和行级锁,表级锁锁住全表,对并发操作性能影响非常大 |
Q有没有一种能够解决方案:既能数据一致,又能保证并发的性能得到发挥? | A: InnoDB 的行级锁,他是需要配合事务来实现的! |
行级锁在 mysql-3行级锁 中以及做了详细的分析,下面就介绍下事务的概念吧
InnoDB-事务 : 事务的特性是ACID
Automic | 原子性 | 在一个事务内部,所有的事情要不全都执行成功,要不全都失败 |
Consistency | 一致性 | 在同一个事务内部数据value不可能出现多种情况 |
Isolation | 隔离性 | 一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。 (事务之间的隔离级别:read uncommit / read commit / repare -read / serialized) |
Duration | 持久性 | 每一次操作都会在数据库中生成一条日志信息,保证数据的持久性存储,事务一旦提交,它对数据库中数据的改变就应该是永久性的 |
这里主要讨论的是隔离性:
read-uncommit | 未提交-读 | 在一个事务内部进行了写操作还没提交之前 , 另外的事务就可以读取到修改的内容 | 脏读 | 幻读 |
read-commit | 已提交-读 | 在一个事务内部进行写操作,只有在提交之后,另外的事务内部才能读取到修改内容 | 幻读 | |
repeatable-read | 可重复度 | 在一个A事务进行写操作提交之前,如果有另外其他事务开启了,A事务提交不提交对于其他事物的select结果都不会有影响 | 幻读 | |
serialized | 串行化 | 在多个事务开启了之后,执行写操作只有一个事物能执行 |
具体的实现,我们这里来操作一把:
先查看mysql的默认事务隔离级别
开启事务的方式:BEGIN / START TRANSCATION / BEGIN WORK
提交事务 COMMIT
回滚事务 ROLLBACK
还原点 SAVEPOINT ---------需要先确认事务是否自动提交
这里我们从未提交读依次往下来验证:
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
事务隔离级别为可重复读时,如果有索引(包括主键索引)的时候,以索引列为条件更新数据,会存在间隙锁间、行锁、页锁的问题,从而锁住一些行;如果没有索引,更新数据时会锁住整张表
事务隔离级别为串行化时,读写数据都会锁住整张表
隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大,对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed,它能够避免脏读取,而且具有较好的并发性能。