一、MySQL事务是什么?
事务是指作为单个逻辑工作单元一系列操作,要么全部执行成功,要么全部执行失败。常见的业务场景比如:A用户使用自己银行账户转账200元到B用户的账户,那么至少需要三个步骤:
- 检查A用户银行账号余额是否大于200元。
- A用户的银行账户减去200元。
- B用户的银行账户添加200元。
以上三个步骤必须作为一个事务,只要其中一个步骤失败,那么全部的步骤都要进行回滚。上面举了关于事务的业务场景,那如何定义事务呢,一般来说事务具有四大特性(ACID):原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。
-
原子性:一个事务中的所有操作,要么全部执行成功,要么全部执行失败。只要中间一个环节出现错误,就要进行全部回滚到最初状态,就好像没有执行过一样.
-
一致性:数据库在事务执行前后必须保持一致。
-
隔离性:事务所做的修改在最终提交前,对其他事务是不可见。
-
持久性:事务所做的修改一旦提交,就会永久保存在数据库里。
二、事务并发三大问题
一个数据库可以被多个客户端同时访问,而数据库相同的数据可能被多个事务同时访问,如果事务没有采取隔离措施,就会导致各种并发问题,破坏数据库数据完整性。事务并发问题归为三大类:脏读(dirty read)、不可重复读(nonrepeatable)、幻读(phantom row)
- 脏读:事务修改未提交的数据被其他事务读取到。
- 不可重复读:读取了其他事务修改已提交的数据,针对update。比如同一个事务使用相同的select语句,执行两次得到不一样的结果。
- 幻读:读取了其他事务修改已提交的数据,针对insert、delete。比如同一个事务使用相同的select语句进行查询接着其他事务插入新的行,然后在执行相同的select语句查询,看到了新增的行,这就是幻读。
三、事务的隔离级别
事务的隔离级别主要是解决事务的并发问题。SQL92 ANSI/ISO标准定义了四种隔离级别:
-
未提交读(read uncommitted)
-
已提交读(read committed)
-
可重复读(repeatable read)
-
序列化(serializable)
MySQL InnoDB存储引擎事务默认的隔离级别是可重复读,以下表格展示的是MySQL InnoDB存储引擎对事务隔离级别支持的程度。
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
未提交读 | 可能 | 可能 | 可能 |
已提交读 | 不可能 | 可能 | 可能 |
可重复读 | 不可能 | 不可能 | 不可能 |
序列化 | 不可能 | 不可能 | 不可能 |
四、事务开启
MySQL的事务默认是自动提交的,每一条SQL语句会被当做一个事务来处理。因此想要显式的执行事务,可以通过以下命令操作。
start transaction(开启事务)
commit (提交事务)
rollback (回滚事务)
五、总结
本文主要讲解了事务的四大特性(ACID),并发事务的三大问题,并且我们可以知道事务的并发问题是通过事务隔离级别来解决。实际上 InnoDB存储引擎事务隔离级别的可重复读已经解决了不可重复读和幻读问题。