文章目录
什么是事务?
事务是一个最小的不可再分的工作单元,通常一个事务对应一个完整的业务的数据操作;事务内的操作要么全部成功,要么全部失败。
例如银行转账:
A 转账 1000 给 B,这其中要涉及检查 A 账户的余额, A 的扣款、B 的到账等一系列操作,这组操作就是一个事务。如果一切正常那就相安无事,一旦中间有某个环节异常,那整个事务就要回滚。不然就会出现数据不一致的问题,问题就很严重。
注意:在 MySQL 中只有使用了 Innodb 数据库引擎的表才支持事务。
事务的作用
-
提供一个可靠的工作单元,能够从失败中恢复到正确的状态。如果发生系统错误,执行操作语句中断(全部中断或部分中断)或者是许多操作没有完成或不知道其状态下,依旧保持数据库正常运行。
-
在程序访问数据库之间提供一个隔离。如果不提供这种隔离,程序可能返回不准确的结果。
事务类型
- 自动提交的事务 – 每一个单独的语句都是一个事务,系统自动开启,自动提交。
- 显示声明的事务 – 明显的以 BEGIN 或 START TRANSACTION 开始,并且以 COMMIT 或者 ROLLBACK 结尾的语句。
事务的特性
一般来说,事务是必须满足4个条件(ACID)::原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。
- 原子性: 事务(transaction)是一个原子操作单元,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
- 一致性: 在事务开始和完成时,数据都必须保持一致状态。比如上面转账的例子,A向B转账,不存在A扣了钱,B却没收到的情况。
- 隔离性: 数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括未提交读(Read uncommitted)、已提交读(read committed)、可重复读(repeatable read)和串行化(Serializable)。
- 持久性: 事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
在 MySQL 默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。因此要显式地开启一个事务务须使用命令 BEGIN 或 START TRANSACTION,或者执行命令 SET AUTOCOMMIT=0,用来禁止使用当前会话的自动提交。
并发事务带来的问题
- 更新丢失:当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生更新丢失问题——即最后的更新覆盖了其他事务所做的更新。
- 脏读:A事务正在对一条记录做修改,在这个事务完成并提交前,这条记录的数据就处于不一致的状态;这时,