📜  DBMS 中的事务隔离级别(1)

📅  最后修改于: 2023-12-03 15:30:23.658000             🧑  作者: Mango

DBMS 中的事务隔离级别

什么是事务

在数据库中,事务(Transaction)是一系列要么全部执行成功,要么全部执行失败的操作。事务通常是由 SQL 语句组成,这些语句可以是 SELECT、INSERT、UPDATE、DELETE 等等。

在 DBMS 里,事务具有以下四个特性,通常称之为一个事务的 ACID 特性:

  • 原子性(Atomicity):事务应该是一个原子操作,不可分割。
  • 一致性(Consistency):事务执行前后,数据库所处的状态应该是一致的。
  • 隔离性(Isolation):多个事务并发执行时,它们是相互隔离的,互相不干扰,也就是说,每个事务在看待数据时,都好像是它在单独执行。
  • 持久性(Durability):事务执行成功后,其修改的内容在数据库中是永久性地保存的。
事务隔离级别

在 DBMS 中,为了实现隔离性,引入了事务隔离级别(Transaction Isolation Level)的概念。事务隔离级别定义了一个事务可能探测到的其他事务的影响范围。

经常被用来描述事务隔离级别的有四个词:脏读(Dirty Read)不可重复读(Non-repeatable Read)幻读(Phantom Read)超时(Timeout)

DBMS 标准提供了四种事务隔离级别,每个级别都规定了一个事务可能看到的数据变更的级别。

读未提交(Read Uncommitted)

在最低隔离级别下,一个事务可以读到另一个正在执行的事务没有提交的数据变更(即脏读),这是最低的隔离级别。

这个级别很少被使用,因为它的使用场景非常有限。如果遇到多个正在执行的事务,这些事务都没有提交,造成的混乱可能会难以处理。

读已提交(Read Committed)

一个事务只能读取其他在它执行开始前已经提交的事务所修改的数据(这个级别又称为“不可重复读”操作)。也就是说,在一个事务中,A 操作读取数据后发现不满足条件,需要等待 B 事务对数据做出修改,A 事务重新读取到新的数据才能继续执行。

这个隔离级别保证了不会读到“脏数据”,如果它已经提交,那么读取的数据就是最新的。

可重复读(Repeatable Read)

在这个隔离级别下,一个事务在执行时多次读取相同数据,其结果是一致的。

在可重复读级别下,读操作的锁定是在事务执行过程中始终有效的,直到事务结束才会释放锁定。由于数据不能被修改,所以这个级别避免了“脏数据”和“不可重复读”问题。

可串行化(Serializable)

在可串行化隔离级别下,所有事务都是连续执行的,并且每个事务在提交之前都会持有所有必需的锁定(这个隔离级别又称为“幻象读”操作)。这可以解决“脏数据”、“不可重复读”和“幻读”问题。

当多个事务同时运行时,这个隔离级别性能较差,因为每个事务都阻塞其他事务访问锁定资源直到事务完成。

总结

在 DBMS 中,建议使用可重复读隔离级别,这可以通过使用读取锁定来避免并发修改数据的情况。在某些应用程序中,如果使用更高的隔离级别,会增加系统的响应时间和系统的开销。

下面是一个使用 Python 连接 PostgreSQL 数据库并设置事务隔离级别的示例:

import psycopg2

conn = psycopg2.connect("dbname=test user=dbuser password=dbpass")
conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_REPEATABLE_READ)