>  기사  >  데이터 베이스  >  mysql 트랜잭션 격리 수준은 무엇입니까?

mysql 트랜잭션 격리 수준은 무엇입니까?

青灯夜游
青灯夜游원래의
2023-01-04 16:37:5915816검색

4가지 트랜잭션 격리 수준이 있습니다. 1. 커밋되지 않은 읽기(커밋되지 않은 읽기) - 더티 읽기, 반복 불가능한 읽기 및 팬텀 읽기를 유발할 수 있는 커밋되지 않은 데이터 변경 사항을 읽을 수 있습니다. 2. 커밋된 읽기(Read Committed)는 동시 트랜잭션에 의해 제출된 데이터 읽기를 허용하므로 더티 읽기를 방지할 수 있지만 반복 불가능하고 팬텀 읽기가 발생할 수 있습니다. 3. 반복 읽기(반복 읽기), 동일한 필드를 여러 번 읽으면 결과가 일관됩니다. 4. 직렬화 가능(직렬화 가능).

mysql 트랜잭션 격리 수준은 무엇입니까?

이 튜토리얼의 운영 환경: windows7 시스템, mysql8 버전, Dell G3 컴퓨터.

1. 거래란 무엇인가요?

트랜잭션은 논리적 작업 집합으로, 모두 실행되거나 아무것도 실행되지 않습니다.

가장 고전적이고 자주 언급되는 거래의 예는 은행 송금입니다. 예를 들어, Xiao Ming이 Xiao Hong에게 1,000위안을 이체하려는 경우 이 이체에는 Xiao Ming의 잔액을 1,000위안 줄이고 Xiao Hong의 잔액을 1,000위안 줄이는 두 가지 주요 작업이 포함됩니다. 이 두 작업 사이에 갑자기 오류가 발생하여 Xiao Ming의 잔액이 감소하고 Xiao Hong의 잔액이 증가하지 않는 경우, 이러한 상황은 절대 허용되지 않습니다. 트랜잭션은 이 두 가지 주요 작업이 성공하거나 둘 다 성공하지 못하도록 보장하는 것입니다.

2. 트랜잭션 특성(ACID)

  • **원자성: **트랜잭션의 최소 실행 단위, 분할은 허용되지 않습니다. 트랜잭션의 원자성은 작업이 모두 실행되거나 전혀 실행되지 않도록 보장합니다.
  • **일관성:**트랜잭션 실행 전후에 데이터가 일관되게 유지됩니다. 예를 들어, 자금 이체 사업에서는 거래의 성공 여부에 관계없이 송금인과 수취인 간의 총액이 변경되지 않고 유지되어야 합니다.
  • ** 격리: ** 데이터베이스에 동시에 액세스할 때 사용자의 트랜잭션은 다른 트랜잭션의 영향을 받아서는 안 되며, 데이터베이스는 동시 트랜잭션 간에 독립적입니다.
  • **지속성:**트랜잭션이 커밋된 후 데이터베이스의 데이터 변경 사항은 내구성이 있으므로 데이터베이스가 실패하더라도 영향을 받아서는 안 됩니다.

3. 동시 트랜잭션으로 인한 문제

일반적인 애플리케이션에서는 여러 트랜잭션이 동시에 실행되고 동일한 데이터에서 작동하여 해당 작업을 완료하는 경우가 많습니다(여러 사용자가 동일한 데이터에서 작동). 동시성이 필요하지만 다음과 같은 문제가 발생할 수 있습니다.

  • **더티 읽기: **트랜잭션이 데이터에 액세스하여 수정하고 있지만 아직 트랜잭션을 제출하지 않은 경우 다른 트랜잭션도 이 데이터에 액세스한 후 사용했습니다. 이 데이터의 수정 사항이 데이터베이스에 제출되지 않았기 때문에 다른 트랜잭션에서 읽은 데이터는 "더티 데이터"입니다. 이 동작은 "더티 데이터"에 기반한 작업입니다. "라는 문제가 발생할 수 있습니다.
  • 수정 손실:
  • 한 트랜잭션이 하나의 데이터를 읽을 때 다른 데이터도 해당 데이터에 액세스한 다음 첫 번째 트랜잭션이 데이터를 수정한 후 두 번째 트랜잭션도 이 데이터를 수정한다는 의미입니다. 이런 식으로 첫 번째 트랜잭션의 수정 결과가 손실되는 상황을 수정 손실이라고 합니다. 예: 트랜잭션 1은 테이블의 데이터를 읽지만 트랜잭션 1의 수정 기록은 손실됩니다. A=20,事务2也读取A=20,事务1修改A=A-1,事务2也修改A=A-1,最终结果都是19반복 불가능한 읽기:
  • 트랜잭션이 종료되기 전에 다른 트랜잭션도 해당 데이터에 액세스하여 데이터를 수정하는 경우 첫 번째 트랜잭션에서 두 번 읽은 데이터가 일치하지 않는 것을 말합니다. 이러한 상황을 반복 불가능 읽기라고 합니다.
  • 팬텀 읽기: 팬텀 읽기는 반복 불가능한 읽기와 유사합니다. 팬텀 읽기는 트랜잭션이 여러 행의 데이터를 읽는 것을 의미합니다. 트랜잭션이 아직 종료되지 않은 후 다른 트랜잭션이 일부 데이터를 삽입한 다음 다른 트랜잭션이 삽입됩니다. 쿼리에서 첫 번째 트랜잭션은 마치 환각이 발생한 것처럼 원래 읽은 것보다 더 많은 데이터를 읽게 되므로 이를
  • 유령 읽기
  • 라고 합니다.
  • 비반복 읽기와 환상 읽기의 차이점:

비반복 읽기의 초점은 수정에 중점을 두는 반면 환상 읽기의 초점은 추가 또는 삭제에 있습니다. 밤 1 (동일한 조건, 다시 읽으면 읽는 데이터가 달라짐): 거래 1의 A씨는 급여가 1,000이라고 읽었으며 거래 2의 B씨는 I입니다. A씨의 급여를 2000으로 수정했습니다. A씨가 급여를 다시 읽으면 2000이 됩니다. 이는 반복할 수 없는 읽기입니다.

밤나무 2(동일 조건, 첫 번째와 두 번째로 읽는 레코드 수가 다름): 급여 테이블에 급여가 3,000보다 큰 사람이 4명이 있는 경우 트랜잭션 1은 급여가 더 큰 레코드를 모두 읽습니다. 3,000개 이상 총 4개의 레코드가 조회되었으며, Transaction 2에서 급여가 3,000이 넘는 다른 레코드를 조회하였고, Transaction 1이 조회된 레코드를 다시 읽어보니 조회된 레코드의 개수는 5개였습니다. 이는 팬텀 읽기입니다.

4. 트랜잭션 격리 수준

SQL 표준은 4가지 격리 수준을 정의합니다.

  • **READ-UNCOMMITTED:**아직 커밋되지 않은 읽기를 허용하는 가장 낮은 격리 수준입니다. 더티 읽기(dirty read), 반복 불가능한 읽기, 팬텀 읽기(phantom read)가 있습니다.
  • ** READ-COMMITTED: ** 동시 트랜잭션으로 제출된 데이터 읽기를 허용합니다.
  • 더티 읽기를 방지할 수 있지만 반복 불가능하고 팬텀 읽기가 발생할 수 있습니다.
  • **반복 읽기(REPEATABLE-READ): **트랜잭션 자체가 수정되지 않는 한 동일한 필드에 대한 여러 읽기의 결과는 일관됩니다.
  • 더티 읽기 및 반복 불가능 읽기는 피할 수 있지만 팬텀 읽기가 발생할 수 있습니다. .
  • ** 직렬화 가능: ** ACID 격리 수준을 완전히 준수하는 가장 높은 격리 수준, 모든 트랜잭션이 순서대로 실행됩니다.
  • 더티 읽기, 반복 불가능 읽기 및 팬텀 읽기를 방지할 수 있습니다.
격리 수준더티 읽기반복 불가능한 읽기팬텀 읽기커밋되지 않은 읽기√√√읽음 제출됨

MySQL InnoDB스토리지 엔진의 기본 트랜잭션 격리 수준은 반복 읽기(REPEATABLE-READ)이며, select @@tx_isolation; 명령을 통해 전달할 수 있습니다. 문 확인을 위해 MySQL 8.0 이 문은 SELECT @@transaction_isolation;MySQL InnoDB存储引擎默认的事务隔离级别是可重复读(REPEATABLE-READ),可以通过命令select @@tx_isolation;语句来查看,MySQL 8.0 该语句改为SELECT @@transaction_isolation;

mysql> SELECT @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+

MySQL InnoDB存储引擎的可重复读并不能避免幻读,需要应用使用加锁读来保证,这加锁读使用到的机制就是Next-Key Locks

因为隔离级别越低,事务请求的锁越少,所以大部分数据库系统的隔离级别都是读取已提交(READ-COMMITTED)InnoDB 存储引擎默认使用 REPEATABLE-READ(可重读) 并不会有任何性能损失。

InnoDB存储引擎在分布式事务的情况下一般会用到可串行化隔离级别。

? 拓展一下(以下内容摘自《MySQL 技术内幕:InnoDB 存储引擎(第 2 版)》7.7 章):

InnoDB存储引擎提供了对XA事务的支持,并通过XA事务来支持分布式事务的实现。分布式事务指的是允许多个独立的事务资源参与到一个全局的事务中。事务资源通常是关系型数据库系统,但也可以是其他类型的资源。全局事务要求在其中的所有参与的事务要么都提交,要么都回滚,这对事务的原有ACID要求又有了提高。另外,在使用分布式事务时,InnoDB 存储引擎的事务隔离级别必须设置为 SERIALIZABLE。

四、实际情况演示

MySQL命令行的默认配置中事务都是自动提交的,即执行SQL语句就会马上执行COMMIT操作。可以用命令START TRANSACTION开始一个事务。

我们可以通过下面命令设置事务隔离级别。

SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE]

我们再来看一下我们在实际操作中使用到的一些并发控制语句:

  • START TRANSACTION | BEGIN :显示的开启一个事务。
  • COMMIT:提交事务,使得对数据库做的所有修改成为永久性。
  • ROLLBACK:回滚到结束用户的事务,并撤销正在进行的所有未提交的修改。

(脏读)读取未提交

(避免脏读)读取已提交

不可重复读

还是刚才上面的读已提交的图,虽然避免了读未提交,但是却出现了,一个事务还没有结束,就发生了 不可重复读问题。

可重复读

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ysjbfC4b-1651149978452)(https://qtspace.cn/contentimg/81.jpg)]

幻读

演示幻读出现的情况

sql 脚本 1 在第一次查询工资为 500 的记录时只有一条,sql 脚本 2 插入了一条工资为 500 的记录,提交之后;sql 脚本 1 在同一个事务中再次使用当前读查询发现出现了两条工资为 500 的记录这种就是幻读。

幻读和不可重复读有些相似之处 ,但是不可重复读的重点是修改,幻读的重点在于新增或者删除。

解决幻读的方法

  • 将事务隔离级别调整为 SERIALIZABLE
  • 在可重复读的事务级别下,给事务操作的这张表添加表锁。
  • 在可重复读的事务级别下,给事务操作的这张表添加 Next-Key Locks

说明:Next-Key Locksrrreee

MySQL InnoDB로 변경되었습니다. 반복 가능 스토리지 엔진의 읽기 및 병합 팬텀 읽기는 피할 수 없으며 애플리케이션은 잠긴 읽기에 사용되는 메커니즘이 다음 키 잠금인지 확인하기 위해 잠긴 읽기를 사용해야 합니다.

격리 수준이 낮을수록 트랜잭션에서 요청하는 잠금 수가 적어지므로 대부분의 데이터베이스 시스템의 격리 수준은 READ-COMMITTED, InnoDB입니다. 스토리지 엔진은 REPEATABLE-READ(재읽기 가능)는 기본적으로 성능 저하 없이 실행됩니다. InnoDB스토리지 엔진은 일반적으로 분산 트랜잭션의 경우 직렬화 가능 격리 수준을 사용합니다.

🎜? 확장(다음 내용은 "MySQL 기술 내부자: InnoDB 스토리지 엔진(2판)"의 7.7장에서 발췌): 🎜
🎜InnoDB 스토리지 엔진은 XA 트랜잭션을 지원하고 XA 트랜잭션을 통한 배포를 지원합니다. 공식적인 거래. 분산 트랜잭션은 여러 개의 독립적인 트랜잭션 리소스가 글로벌 트랜잭션에 참여할 수 있도록 허용하는 것을 의미합니다. 트랜잭션 리소스는 일반적으로 관계형 데이터베이스 시스템이지만 다른 유형의 리소스일 수도 있습니다. 전역 트랜잭션에서는 참여하는 모든 트랜잭션을 커밋하거나 롤백해야 하므로 트랜잭션에 대한 원래 ACID 요구 사항이 더욱 향상됩니다. 또한 분산 트랜잭션을 사용하는 경우 InnoDB 스토리지 엔진의 트랜잭션 격리 수준을 SERIALIZABLE로 설정해야 합니다. 🎜🎜

🎜4. 실제 상황 시연

🎜MySQL명령줄의 기본 구성에서 트랜잭션은 자동으로 제출됩니다. 즉, SQL 문을 실행하면 즉시 COMMIT 작업이 실행됩니다. START TRANSACTION 명령을 사용하여 트랜잭션을 시작할 수 있습니다. 🎜🎜다음 명령을 통해 트랜잭션 격리 수준을 설정할 수 있습니다. 🎜rrreee🎜실제 작업에서 사용하는 동시성 제어 문 중 일부를 살펴보겠습니다. 🎜
  • START BEGIN: 트랜잭션을 명시적으로 엽니다.
  • COMMIT: 트랜잭션을 커밋하여 데이터베이스에 대한 모든 수정 사항을 영구적으로 만듭니다.
  • ROLLBACK: 사용자 트랜잭션의 끝으로 롤백하고 진행 중인 커밋되지 않은 모든 수정 사항을 실행 취소합니다.

🎜(더티 읽기) 커밋되지 않은 읽기

🎜🎜

🎜 (더티 읽기 방지) 읽기 제출됨 강함>

🎜🎜🎜반복 불가능한 읽기🎜 여전히 바로 위의 읽기 커밋된 그림입니다. 커밋되지 않은 읽기를 방지하지만 끝나기 전에 반복 불가능한 트랜잭션이 나타납니다. 읽기 문제가 발생했습니다. 🎜🎜🎜

🎜반복 읽기

🎜[외부 링크 이미지 전송에 실패했습니다. 소스 사이트에 리칭 방지 메커니즘이 있을 수 있습니다. 이미지를 저장하고 직접 업로드하는 것이 좋습니다(img-ysjbfC4b). -1651149978452) (https: //qtspace.cn/contentimg/81.jpg)]🎜

🎜팬텀 리딩

🎜의 발생을 입증합니다. 유령 읽기🎜🎜🎜🎜sql 스크립트 1은 다음을 사용하여 레코드를 쿼리합니다. 처음으로 급여 500 당시에는 레코드가 하나뿐이었습니다. SQL 스크립트 2는 급여가 500인 레코드를 삽입했습니다. 제출 후 SQL 스크립트 1은 동일한 트랜잭션에서 현재 읽기 쿼리를 다시 사용하여 다음과 같은 두 개의 레코드를 발견했습니다. 500의 급여가 나타났습니다. 이것은 환상의 읽기입니다. 🎜🎜환상 읽기와 비반복 읽기는 다소 비슷하지만, 환상 읽기의 초점은 추가 또는 삭제에 중점을 두는 반면, 환상 읽기의 초점은 수정입니다. 🎜🎜팬텀 읽기 문제를 해결하는 방법🎜
  • 트랜잭션 격리 수준을 SERIALIZABLE로 조정하세요.
  • 반복 읽기 트랜잭션 수준에서 트랜잭션 작업의 테이블에 테이블 잠금을 추가합니다.
  • 반복 가능한 읽기 트랜잭션 수준에서 트랜잭션 작업을 위한 테이블에 다음 키 잠금을 추가하세요.
🎜설명: 다음 키 잠금은 행 잠금 + 간격 잠금과 동일합니다🎜🎜🎜[관련 권장 사항: 🎜mysql 비디오 튜토리얼🎜]🎜
🎈

위 내용은 mysql 트랜잭션 격리 수준은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.