事务基本概念
事务(Transaction)是并发控制的单位,是用户定义的一个操作序列。这些操作要么都做,要么都不做,是一个不可分割的工作单位。通过事务,SQL中将逻辑相关的一组操作绑定在一起,以便服务器保持数据的完整性。
事务通常是以BEGIN TRANSACTION开始,以COMMIT或ROLLBACK结束。
COMMIT表示提交,即提交事务的所有操作。具体地说就是将事务中所有对数据库的更新写回到磁盘上的物理数据库中去,事务正常结束。
ROLLBACK表示回滚,即在事务运行的过程中发生了某种故障,事务不能继续进行,系统将事务中对数据库的所有以完成的操作全部撤消,滚回到事务开始的状态。
事务的特性(ACID特性)
A:原子性(Atomicity)
事务是数据库的逻辑工作单位,事务中包括的所有操作要么全做,要么全不做。
B:一致性(Consistency)
事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
C:隔离性(Isolation)
一个事务的执行不能被其他事务干扰。
D:持续性/永久性(Durability)
一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。
事务的使用场景示例:
简单例子银行转帐,如果甲把钱汇出去了,但是银行发生了点问题,钱没有汇到乙的钱包里,那钱怎么办。
这个时候如果用上事务,钱就会回退给甲,一个减少,一个增加,要么执行,要么不执行。
start transaction;
update t_account set amount=amount-1000 where account_id=甲的账号id;
update t_account set amount=amount+1000 where account_id=乙的账号id;
commit;
事务隔离
SQL标准用三个必须在并发的事务之间避免的现象定义了四个级别的事务隔离。 这些不希望发生的现象是:
脏读:一个事务读取了另一个未提交事务写入的数据。
不可重复读:一个事务重新读取前面读取过的数据,发现该数据已经被另一个已提交事务修改。
幻读:一个事务重新执行一个查询,返回一套符合查询条件的行,发现这些行因为其它最近提交的事务而发生了改变。
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 | 可能 | 可能 | 可能 |
读已提交 | 不可能 | 可能 | 可能 |
重复读 | 不可能 | 不可能 | 可能 |
可串行化 | 不可能 | 不可能 | 不可能 |
实际在内部只有两种独立的隔离级别,分别对应读已提交和可串行化。
如果你选择了读未提交的级别,实际上你用的是读已提交,在你选择可重复读级别的时候, 实际上你用的是可串行化,所以实际的隔离级别可能比你选择的更严格。这是 SQL 标准允许的:四种隔离级别只定义了哪种现象不能发生,但是没有定义那种现象一定发生。