数据库事务:ACID 和隔离级别

一、什么是事务

事务是将多条 SQL 作为一个整体进行数据操作。这样能确保全部执行成功或全部执行失败,不改变任何数据。根据业务需求选择不同的存储引擎。对于那些不需要事务的查询类应用,选择非事务型的存储引擎能得到更高的性能,LOCK TABLES 也能为应用提供一定程度的保护。

二、怎样使用

  • 开始事务:START TRANSACTION 或者 BEGIN

  • 提交事务持久保存已修改的数据:COMMIT

  • 回滚撤销数据修改:ROLLBACK

三、应用场景

比较经典的应用就是转账操作,你要给 A 转 100 块,正常来说你的账号会减少 100 块,而 B 的账号会增加 100 块。但是转账过程中系统突然崩溃暴毙,导致你的账号是减少了 100 块,但 A 的账号并没有增加,这样是不是就很离谱了。所以说我们需要将这两个操作作为一个整体来实现,要么全部成功,要是有一个没执行成功,那就全部失败。

START TAANSACTION; 或者 BEGIN; -- 开始一个事务
UPDATE Gnahzi SET balance = balance - 100 WHERE id = 1;
UPDATE zhang SET balance = balance + 100 WHERE id = 2;
COMMIT; 或者 ROLLBACK; -- COMMIT 是提交事务把修改的数据持久保存;ROLLBACK 是回滚事务取消操作。

四、事务的 4 个特性:ACID

  • 原子性(Acomicity):一个事务是最小工作单元。不可能只执行其中一个操作,要么全部执成功,要么就全部失败回滚。

  • 一致性(Consistency):一致性确保当 SQL 语句执行时系统崩溃,事务所做的修改不会保存到数据库中,因为事务最终没有提交。

  • 隔离性(Isolation):通常来说,一个事务所做的修改在最终提交前,对其它事务是不可见的。

  • 持久性(Durability):一旦事务提交,所做的修改会永久保存到数据库中。即使系统崩溃了,修改的数据也不会丢失。

五、事务的 4 个隔离级别:

  • 未提交读(READ UNCOMMITTED):事务可以读取未提交的数据,也称作脏读(Dirty Read)。一般很少使用。

  • 提交读 | 不可重复读(READ COMMITTED):是大都是 DBMS (如:Oracle、SQLServer)默认事务隔离。执行两次同意的查询却有不同的结果,也叫不可重复读。

  • 可重复读(REPEABLE READ):是 MySQL 默认事务隔离级别。能确保同一事务多次读取同一数据的结果是一致的。可以解决脏读的问题,但理论上无法解决幻读(Phantom Read)的问题。

  • 可串行化(SERIALIZABLE):是最高的隔离级别。强制事务串行执行,会在读取的每一行数据上加锁,这样虽然能避免幻读的问题,但也可能导致大量的超时和锁争用的问题。很少会应用到这种级别,只有在非常需要确保数据的一致性且可以接受没有并发的应用场景下才会考虑。

Isolation Level 脏读可能性(Dirty Read) 不可重复读可能性(Non Repeatable Read) 幻读可能性(Phantom Read)
Read Uncommitted Yes Yes Yes
Read Committed - Yes Yes
Repeatable Read - - Yes
Serializable - - -
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章