>데이터 베이스 >MySQL 튜토리얼 >데이터베이스 트랜잭션 및 MySQL 트랜잭션 요약

데이터베이스 트랜잭션 및 MySQL 트랜잭션 요약

coldplay.xixi
coldplay.xixi앞으로
2020-12-30 16:33:522537검색

mysql tutorial데이터베이스 트랜잭션 및 MySQL 트랜잭션 요약

데이터베이스 트랜잭션 및 MySQL 트랜잭션 요약

권장(무료): mysql tutorial

트랜잭션 기능: ACID

비즈니스 관점에서 보면, 예 4가지 특성을 유지하려면 데이터베이스의 작업 집합이 필요합니다.

  • 원자성: 트랜잭션은 분할할 수 없는 최소 작업 단위로 간주되어야 합니다. 전체 트랜잭션의 모든 작업은 성공적으로 제출되거나 모두 실패하여 롤링되어야 합니다. , 트랜잭션의 경우 일부 작업만 수행하는 것은 불가능합니다.
  • 일관성: 데이터베이스는 항상 한 일관성 상태에서 다른 일관성 상태로 전환됩니다. 다음 은행 예를 언급하겠습니다.
  • 격리: 일반적으로 한 트랜잭션에서 수정한 사항은 최종적으로 커밋되기 전에 다른 트랜잭션에 표시되지 않습니다. 여기서는 "일반적으로 말하면"이라는 점에 유의하세요. 이에 대해서는 나중에 트랜잭션 격리 수준에서 설명하겠습니다.
  • 내구성: 트랜잭션이 커밋되면 수정 사항이 데이터베이스에 영구적으로 저장됩니다. 이때 시스템이 충돌하더라도 수정된 데이터는 손실되지 않습니다. (지속성 보안과 로그 새로 고침 수준 사이에도 일정한 관계가 있습니다. 수준에 따라 데이터 보안 수준이 다릅니다.)

ACID를 더 잘 이해하려면 은행 계좌 이체를 예로 들어보세요.

START TRANSACTION;SELECT balance FROM checking WHERE customer_id = 10233276;UPDATE checking SET balance = balance - 200.00 WHERE customer_id = 10233276;UPDATE savings SET balance = balance + 200.00 WHERE customer_id = 10233276;COMMIT;
  • 원자성: 완전히 커밋(10233276의 확인 잔액이 200으로 감소하고 저축 잔액이 200으로 증가) 또는 완전히 롤백(두 테이블의 잔액이 변경되지 않음)
  • 일관성: 이 예의 일관성 데이터베이스 시스템이 3행까지 실행된 후 트랜잭션이 아직 커밋되지 않았기 때문에 4행 이전에 충돌이 발생하고 사라집니다.
  • 격리: 한 트랜잭션의 작업 문은 다른 트랜잭션의 문과 격리될 수 있습니다. 예를 들어 트랜잭션 A가 라인 3 이후 및 라인 4 이전에 실행될 때 트랜잭션 B가 당좌 잔액을 쿼리할 때 여전히 가능합니다. 거래 A와 B가 서로 분리되어 있기 때문에 거래 A에서 200위안이 차감되었습니다(계좌 자금은 변경되지 않음). 트랜잭션 A가 커밋되기 전에 트랜잭션 B는 데이터 변경 사항을 관찰할 수 없습니다.
  • 끈기: 이해하기 쉽습니다.
  • 트랜잭션 격리는 잠금, MVCC 등을 통해 달성됩니다. (MySQL 잠금 요약)
  • 트랜잭션의 원자성, 일관성 및 내구성은 트랜잭션 로그를 통해 달성됩니다(아래 참조)

트랜잭션 격리 수준

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

  • Lost Update: 둘 이상의 트랜잭션이 동일한 행을 선택한 후 원래 선택한 값을 기준으로 행을 업데이트하는 경우 각 트랜잭션으로 인해 다른 트랜잭션의 존재를 알지 못한 채, 업데이트 손실 문제가 발생합니다. 마지막 업데이트가 다른 트랜잭션에서 수행한 업데이트를 덮어씁니다. 예를 들어, 두 명의 편집자가 동일한 문서의 전자 사본을 만듭니다. 각 편집자는 독립적으로 사본을 변경한 후 변경된 사본을 저장하고 원본 문서를 덮어씁니다. 자신의 변경 사항 사본을 마지막으로 저장한 편집자가 다른 편집자의 변경 사항을 덮어씁니다. 다른 편집자가 트랜잭션을 완료하고 커밋할 때까지 한 편집자가 동일한 파일에 액세스할 수 없는 경우 이 문제를 피할 수 있습니다.
  • 더티 읽기(Dirty Reads): 트랜잭션이 완료되어 제출되기 전에 현재 이 레코드의 데이터가 일치하지 않는 상태입니다. 선택하지 않으면 다른 트랜잭션도 동일한 레코드를 읽습니다. 이러한 "더러운" 데이터를 읽고 그에 따라 추가 처리를 수행하므로 커밋되지 않은 데이터 종속성이 발생합니다. 이런 현상을 '더티 리딩(dirty reading)'이라고 부르기도 합니다.
  • 비반복 읽기: 트랜잭션은 일부 데이터를 읽은 후 이전에 읽은 데이터를 다시 읽지만 읽은 데이터가 변경되었거나 일부 레코드가 삭제되었음을 발견합니다! 이러한 현상을 "반복 불가능한 읽기"라고 합니다.
  • 팬텀 읽기(Phantom Reads): 트랜잭션은 동일한 쿼리 조건에 따라 이전에 검색된 데이터를 다시 읽지만, 다른 트랜잭션이 해당 쿼리 조건을 충족하는 새 데이터를 삽입했음을 발견합니다. 이 현상을 "팬텀 읽기"라고 합니다.

환상 읽기와 비반복 읽기의 차이점:

  • 비반복 읽기의 초점은 수정입니다. 동일한 트랜잭션, 동일한 조건에서 처음 읽은 데이터는 두 번째로 읽은 데이터와 다릅니다. (다른 트랜잭션이 중간에 수정사항을 제출했기 때문입니다.)
  • 팬텀리딩의 핵심은 추가 또는 삭제입니다. 동일한 트랜잭션, 동일한 조건에서 첫 번째와 두 번째로 읽어오는 레코드 수가 다릅니다. (다른 트랜잭션이 중간에 삽입/삭제를 커밋했기 때문입니다.)

동시 트랜잭션 처리로 인해 발생하는 문제에 대한 해결 방법:

  • "업데이트 손실"은 일반적으로 완전히 피해야 합니다. 그러나 업데이트 손실 방지는 데이터베이스 트랜잭션 컨트롤러만으로는 해결할 수 없습니다. 따라서 업데이트할 데이터에 필요한 잠금을 애플리케이션에서 추가해야 합니다. 따라서 업데이트 손실 방지는 애플리케이션의 책임입니다.

  • "더티 읽기", "반복 불가능 읽기" 및 "팬텀 읽기"는 실제로 데이터베이스 읽기 일관성 문제이며 특정 트랜잭션 격리 메커니즘을 제공하는 데이터베이스로 해결해야 합니다.

  • One is locking: Lock 다른 트랜잭션이 데이터를 수정하는 것을 방지하기 위해 데이터를 읽기 전에 먼저 삭제합니다.

  • 다른 하나는 다중 버전 데이터베이스라고도 알려진 데이터 다중 버전 동시성 제어(MVCC 또는 MCC)입니다. 잠금을 추가하지 않고 특정 메커니즘을 통해 데이터 요청 시점의 일관된 데이터 스냅샷이 생성됩니다. (스냅샷), 이 스냅샷을 사용하여 특정 수준(문 수준 또는 트랜잭션 수준)의 일관된 읽기를 제공합니다. 사용자의 관점에서 볼 때 데이터베이스는 동일한 데이터의 여러 버전을 제공할 수 있는 것으로 보입니다.

SQL 표준은 4가지 유형의 격리 수준을 정의합니다. 각 수준은 트랜잭션 내 및 트랜잭션 간에 표시되는 수정 사항과 보이지 않는 수정 사항을 지정합니다. 격리 수준이 낮을수록 일반적으로 더 높은 동시성을 지원하고 시스템 오버헤드가 더 낮습니다.

레벨 1: 커밋되지 않은 읽기(커밋되지 않은 콘텐츠 읽기)

  • 모든 트랜잭션은 커밋되지 않은 다른 트랜잭션의 실행 결과를 볼 수 있습니다.
  • 이 격리 수준은 성능이 그다지 좋지 않기 때문에 실제 응용 프로그램에서는 거의 사용되지 않습니다. 다른 레벨보다
  • 이 레벨로 인한 문제는 - Dirty Read: 커밋되지 않은 데이터를 읽습니다

레벨 2: Read Committed(제출된 콘텐츠 읽기)

  • 이것은 대부분의 경우 기본 격리 레벨입니다. 데이터베이스 시스템(MySQL 기본값은 아님)

  • 격리의 간단한 정의를 충족합니다. 트랜잭션은 커밋된 트랜잭션에 의해 변경된 내용만 볼 수 있습니다.

  • 이 격리 수준의 문제점은 다음과 같습니다. - 반복 불가능 읽기: 반복 불가능 읽기는 다음을 의미합니다. 동일한 트랜잭션에서 똑같은 select 문을 실행하면 다른 결과가 나타날 수 있습니다. 이 상황의 가능한 이유는 다음과 같습니다.

  • 새 커밋으로 인한 교차 트랜잭션이 있어 데이터가 변경됩니다.

  • 데이터베이스가 여러 인스턴스에 의해 운영되는 경우 동일한 트랜잭션의 다른 인스턴스가 해당 인스턴스에 있습니다. 처리 중에 새로운 커밋이 발생할 수 있습니다

레벨 3: 반복 읽기(다시 읽기 가능)

  • 이것은 MySQL의 기본 트랜잭션 격리 수준입니다
  • 동일한 트랜잭션의 여러 인스턴스를 동시에 읽을 수 있도록 보장합니다.
  • 이 수준에서 발생할 수 있는 문제 - 팬텀 읽기: 사용자가 특정 범위의 데이터 행을 읽을 때, 사용자가 데이터 행을 읽을 때 다른 트랜잭션이 해당 범위에 다른 데이터 행을 삽입합니다. 이 범위에서 새로운 "팬텀" 행을 발견합니다. InnoDB 및 Falcon 스토리지 엔진은 다중 버전 동시성 제어(MVCC, Multiversion Concurrency Control) 메커니즘을 통해 팬텀 읽기 문제를 해결합니다. 팬텀 읽기 문제도 갭 잠금을 통해 해결됩니다.

다중 버전 동시성 제어:Mysql의 대부분의 트랜잭션 스토리지 엔진 구현은 단순한 행 수준 잠금이 아닙니다. 동시성 향상을 고려하여 Oracle, PostgreSQL 등 MVCC(다중 버전 동시성 제어)가 일반적으로 동시에 구현됩니다. 그러나 구현은 다양합니다.

MVCC는 특정 시점의 데이터 스냅샷을 저장하여 구현됩니다. 즉, 구현하는 데 아무리 오랜 시간이 걸리더라도 각 항목에서 표시되는 데이터는 일관됩니다.

낙관적 동시성 제어와 비관적 동시성 제어로 구분됩니다.

MVCC 작동 방식: InnoDB의 MVCC는 각 레코드 행 뒤에 두 개의 숨겨진 열을 저장하여 구현됩니다. 두 컬럼 중 하나는 행 생성 시간을 저장하고, 다른 하나는 행 만료 시간(삭제 시간)을 저장합니다. 물론 저장되는 것은 실시간이 아닌 시스템 버전 번호이다. 새로운 트랜잭션이 시작될 때마다 시스템 버전 번호가 자동으로 추가됩니다. 트랜잭션 시작 시 시스템 버전 번호는 트랜잭션 버전 번호로 사용되며, 비교를 위해 각 레코드 행의 버전 번호를 쿼리하는 데 사용됩니다.

REPEATABLE READ 격리 수준에서 MVCC가 작동하는 방식:

  • SELECT

InnoDB는 다음 조건에 따라 각 행 레코드를 확인합니다.

  1. InnoDB는 버전이 현재 트랜잭션 버전보다 이전인 데이터 행만 찾습니다. 이렇게 하면 트랜잭션에서 읽은 행이 이전에 이미 존재하는지 확인합니다. 트랜잭션 자체에 의해 삽입되거나 수정된 ​​
  2. 행의 삭제 버전 번호가 정의되지 않았거나 현재 트랜잭션 버전 번호보다 큽니다. 이는 트랜잭션이 시작되기 전에 트랜잭션에서 읽은 행이 삭제되지 않았음을 보장합니다. . 위의 두 가지 조건만 충족됩니다.

INSERT

  • InnoDB는 새로 삽입된 각 행의 행 버전 번호로 현재 시스템 버전 번호를 저장합니다.

DELETE

  • InnoDB는 현재 시스템 버전 번호를 저장합니다. 삭제된 각 행에 대한 행 삭제 식별

UPDATE

  • InnoDB는 현재 시스템 버전 번호를 삽입된 새 행의 행 버전 번호로 저장하고, 현재 시스템 버전 번호를 삭제 식별자로 원래 행에 저장합니다.
최대한 활용하려면 이 두 가지 버전 번호를 저장하세요. 작업을 잠글 필요가 없습니다. 이를 통해 데이터 작업이 단순해지고 성능이 향상되며 복잡한 요구 사항에 필요한 행만 읽혀집니다. 단점은 각 레코드 행에 추가 저장 공간, 더 많은 행 확인 및 추가 유지 관리 작업이 필요하다는 것입니다.

MVCC는 COMMITTED READ(읽기 제출) 및 REPEATABLE READ(반복 읽기)의 두 가지 격리 수준에서만 작동합니다.

MVCC는 행 수준 잠금의 변형으로 생각할 수 있지만 많은 경우 잠금 작업을 피하고 오버헤드가 낮습니다. 다양한 데이터베이스의 구현 메커니즘은 다르지만 대부분은 비차단 읽기 작업을 구현하고(읽기에는 잠금이 필요하지 않으며 반복 불가능한 읽기 및 팬텀 읽기는 피할 수 있음) 쓰기 작업은 필요한 행만 잠급니다(쓰기는 반드시 필요함). 잠김) 그렇지 않으면 다른 트랜잭션에 의한 동시 쓰기로 인해 데이터 불일치가 발생합니다.

레벨 4: 직렬화 가능가장 높은 격리 레벨입니다

    트랜잭션이 서로 충돌하지 않도록 강제로 주문하여 팬텀 읽기 문제를 해결합니다. 즉, 읽은 각 데이터 행에 공유 잠금을 추가합니다. MySQL 잠금 요약
  • 이 수준에서는 다수의 시간 초과 및 잠금 경쟁이 발생할 수 있습니다.

격리 수준 비교

각 특정 데이터베이스가 반드시 위의 4가지 격리 수준을 완전히 구현하지는 않습니다. 예:

Oracle은 읽기 커밋 및 직렬화 가능이라는 두 가지 표준 격리 수준만 제공하며 자체 정의된 읽기 전용 격리 수준도 제공합니다.
  • ISO/ANSI SQL92에서 정의한 위의 4가지 격리 수준을 지원합니다. , SQL Server도 "스냅샷"이라는 격리 수준을 지원하지만 엄밀히 말하면 MVCC를 사용하여 구현한 직렬화 가능 격리 수준입니다.
  • MySQL은 4가지 격리 수준을 모두 지원하지만 특정 구현에서는 일부 격리 수준에서 MVCC 일관성 읽기와 같은 일부 기능이 있지만 경우에 따라 그렇지 않은 경우도 있습니다.
  • Mysql은 set transaction 격리 수준 명령을 실행하여 격리 수준을 설정할 수 있습니다. 새 격리 수준은 다음 트랜잭션이 시작될 때 적용됩니다. 예: 세션 트랜잭션 격리 수준 설정 읽기 커밋;

트랜잭션 로그트랜잭션 로그는 트랜잭션 효율성을 높이는 데 도움이 될 수 있습니다.

트랜잭션 로그를 사용하면 스토리지 엔진은 매번 수정된 데이터 자체를 디스크에 유지하는 대신 하드 디스크에 유지되는 트랜잭션 로그에 수정 동작을 복사한 다음 기록합니다.

    트랜잭션 로그는 추가 방식을 사용하므로 로그 쓰기 작업은 디스크의 여러 위치에서 헤드를 이동해야 하는 임의 I/O와 달리 디스크의 작은 영역에서 순차적 I/O이므로 트랜잭션이 사용됩니다. 로깅 방법이 상대적으로 훨씬 빠릅니다.
  • 트랜잭션 로그가 유지된 후 메모리의 수정된 데이터는 백그라운드에서 디스크로 천천히 플러시될 수 있습니다.
  • 데이터 수정 사항이 트랜잭션 로그에 기록되고 지속되었지만 데이터 자체가 디스크에 다시 기록되지 않아 시스템이 충돌하는 경우 스토리지 엔진은 다시 시작할 때 수정된 데이터 중 이 부분을 자동으로 복원할 수 있습니다.
  • 현재 대부분의 스토리지 엔진은 이러한 방식으로 구현됩니다. 일반적으로 이를 미리 쓰기 로깅(Write-Ahead Logging)이라고 합니다.

Mysql의 트랜잭션 구현 원리트랜잭션의 구현은 데이터베이스의 스토리지 엔진을 기반으로 합니다. 스토리지 엔진마다 트랜잭션 지원 수준이 다릅니다. mysql에서 트랜잭션을 지원하는 스토리지 엔진에는 innoDB와 NDB가 있습니다.

innoDB는 mysql의 기본 스토리지 엔진으로 기본 격리 수준은 RR(반복 읽기)이며, RR 격리 수준에서는 한 단계 더 나아가 다중 버전

동시성 제어

를 통해 반복 불가능 읽기 문제를 해결합니다. (MVCC, Multiversion Concurrency Control) 및 갭 잠금(즉, 동시성 제어)을 통해 팬텀 읽기 문제를 해결합니다. 따라서 innoDB의 RR 격리 수준은 실제로 직렬화 수준의 효과를 달성하고 상대적으로 우수한 동시성 성능을 유지합니다.

事务的隔离性是通过锁实现,而事务的原子性、一致性和持久性则是通过事务日志实现。说到事务日志,不得不说的就是redo和undo。

1.redo log

在innoDB的存储引擎中,事务日志通过重做(redo)日志和innoDB存储引擎的日志缓冲(InnoDB Log Buffer)实现。事务开启时,事务中的操作,都会先写入存储引擎的日志缓冲中,在事务提交之前,这些缓冲的日志都需要提前刷新到磁盘上持久化,这就是DBA们口中常说的“日志先行”(Write-Ahead Logging)。当事务提交之后,在Buffer Pool中映射的数据文件才会慢慢刷新到磁盘。此时如果数据库崩溃或者宕机,那么当系统重启进行恢复时,就可以根据redo log中记录的日志,把数据库恢复到崩溃前的一个状态。未完成的事务,可以继续提交,也可以选择回滚,这基于恢复的策略而定。

在系统启动的时候,就已经为redo log分配了一块连续的存储空间,以顺序追加的方式记录Redo Log,通过顺序IO来改善性能。所有的事务共享redo log的存储空间,它们的Redo Log按语句的执行顺序,依次交替的记录在一起。如下一个简单示例:

记录1:

记录2:

记录3:

记录4:

记录5:

2.undo log

undo log主要为事务的回滚服务。在事务执行的过程中,除了记录redo log,还会记录一定量的undo log。undo log记录了数据在每个操作前的状态,如果事务执行过程中需要回滚,就可以根据undo log进行回滚操作。单个事务的回滚,只会回滚当前事务做的操作,并不会影响到其他的事务做的操作。

以下是undo+redo事务的简化过程

假设有2个数值,分别为A和B,值为1,2

1. start transaction;

2. 记录 A=1 到undo log;

3. update A = 3;

4. 记录 A=3 到redo log;

5. 记录 B=2 到undo log;

6. update B = 4;

7. 记录B = 4 到redo log;

8. 将redo log刷新到磁盘

9. commit

在1-8的任意一步系统宕机,事务未提交,该事务就不会对磁盘上的数据做任何影响。如果在8-9之间宕机,恢复之后可以选择回滚,也可以选择继续完成事务提交,因为此时redo log已经持久化。若在9之后系统宕机,内存映射中变更的数据还来不及刷回磁盘,那么系统恢复之后,可以根据redo log把数据刷回磁盘。

所以,redo log其实保障的是事务的持久性和一致性,而undo log则保障了事务的原子性。

Mysql中的事务使用

MySQL的服务层不管理事务,而是由下层的存储引擎实现。比如InnoDB。

MySQL支持本地事务的语句:

START TRANSACTION | BEGIN [WORK] COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE] ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE] SET AUTOCOMMIT = {0 | 1}
  • START TRANSACTION 或 BEGIN 语句:开始一项新的事务。
  • COMMIT 和 ROLLBACK:用来提交或者回滚事务。
  • CHAIN 和 RELEASE 子句:分别用来定义在事务提交或者回滚之后的操作,CHAIN 会立即启动一个新事物,并且和刚才的事务具有相同的隔离级别,RELEASE 则会断开和客户端的连接。
  • SET AUTOCOMMIT 可以修改当前连接的提交方式, 如果设置了 SET AUTOCOMMIT=0,则设置之后的所有事务都需要通过明确的命令进行提交或者回滚

事务使用注意点:

  • 如果在锁表期间,用 start transaction 命令开始一个新事务,会造成一个隐含的 unlock
    tables 被执行。
  • 在同一个事务中,最好不使用不同存储引擎的表,否则 ROLLBACK 时需要对非事
    务类型的表进行特别的处理,因为 COMMIT、ROLLBACK 只能对事务类型的表进行提交和回滚。
  • 和 Oracle 的事务管理相同,所有的 DDL 语句是不能回滚的,并且部分的 DDL 语句会造成隐式的提交。
  • 在事务中可以通过定义 SAVEPOINT(例如:mysql> savepoint test; 定义 savepoint,名称为 test),指定回滚事务的一个部分,但是不能指定提交事务的一个部分。对于复杂的应用,可以定义多个不同的 SAVEPOINT,满足不同的条件时,回滚
    不同的 SAVEPOINT。需要注意的是,如果定义了相同名字的 SAVEPOINT,则后面定义的SAVEPOINT 会覆盖之前的定义。对于不再需要使用的 SAVEPOINT,可以通过 RELEASE SAVEPOINT 命令删除 SAVEPOINT, 删除后的 SAVEPOINT, 不能再执行 ROLLBACK TO SAVEPOINT命令。

自动提交(autocommit):
Mysql默认采用自动提交模式,可以通过设置autocommit变量来启用或禁用自动提交模式

  • 隐式锁定

InnoDB在事务执行过程中,使用两阶段锁协议:

随时都可以执行锁定,InnoDB会根据隔离级别在需要的时候自动加锁;

锁只有在执行commit或者rollback的时候才会释放,并且所有的锁都是在同一时刻被释放。

  • 显式锁定

InnoDB也支持通过特定的语句进行显示锁定(存储引擎层):

select ... lock in share mode //共享锁 select ... for update //排他锁

MySQL Server层的显示锁定:

lock table和unlock table

(更多阅读:MySQL锁总结)

MySQL对分布式事务的支持

分布式事务的实现方式有很多,既可以采用innoDB提供的原生的事务支持,也可以采用消息队列来实现分布式事务的最终一致性。这里我们主要聊一下innoDB对分布式事务的支持。

MySQL 从 5.0.3 开始支持分布式事务,当前分布式事务只支持 InnoDB 存储引擎。一个分布式事务会涉及多个行动,这些行动本身是事务性的。所有行动都必须一起成功完成,或者一起被回滚。

如图,mysql的分布式事务模型。模型中分三块:应用程序(AP)、资源管理器(RM)、事务管理器(TM):

  • 应用程序:定义了事务的边界,指定需要做哪些事务;
  • 资源管理器:提供了访问事务的方法,通常一个数据库就是一个资源管理器;
  • 事务管理器:协调参与了全局事务中的各个事务。

分布式事务采用两段式提交(two-phase commit)的方式:

  • 第一阶段所有的事务节点开始准备,告诉事务管理器ready。
  • 第二阶段事务管理器告诉每个节点是commit还是rollback。如果有一个节点失败,就需要全局的节点全部rollback,以此保障事务的原子性。

分布式事务(XA 事务)的 SQL 语法主要包括:

XA {START|BEGIN} xid [JOIN|RESUME]

虽然 MySQL 支持分布式事务,但是在测试过程中,还是发现存在一些问题:
如果分支事务在达到 prepare 状态时,数据库异常重新启动,服务器重新启动以后,可以继续对分支事务进行提交或者回滚得操作,但是提交的事务没有写 binlog,存在一定的隐患,可能导致使用 binlog 恢复丢失部分数据。如果存在复制的数据库,则有可能导致主从数据库的数据不一致。

如果分支事务在执行到 prepare 状态时,数据库异常,且不能再正常启动,需要使用备份和 binlog 来恢复数据,那么那些在 prepare 状态的分支事务因为并没有记录到 binlog,所以不能通过 binlog 进行恢复,在数据库恢复后,将丢失这部分的数据。

如果分支事务的客户端连接异常中止,那么数据库会自动回滚未完成的分支事务,如果此时分支事务已经执行到 prepare 状态, 那么这个分布式事务的其他分支可能已经成功提交,如果这个分支回滚,可能导致分布式事务的不完整,丢失部分分支事务的内容。
总之, MySQL 的分布式事务还存在比较严重的缺陷, 在数据库或者应用异常的情况下,
可能会导致分布式事务的不完整。如果应用对于数据的完整性要求不是很高,则可以考虑使
用。如果应用对事务的完整性有比较高的要求,那么对于当前的版本,则不推荐使用分布式
事务。                                                         

위 내용은 데이터베이스 트랜잭션 및 MySQL 트랜잭션 요약의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 learnku.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제