mysql tutorial데이터베이스 트랜잭션 및 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;
트랜잭션 격리 수준
동시 트랜잭션으로 인한 문제
환상 읽기와 비반복 읽기의 차이점:
동시 트랜잭션 처리로 인해 발생하는 문제에 대한 해결 방법:
"업데이트 손실"은 일반적으로 완전히 피해야 합니다. 그러나 업데이트 손실 방지는 데이터베이스 트랜잭션 컨트롤러만으로는 해결할 수 없습니다. 따라서 업데이트할 데이터에 필요한 잠금을 애플리케이션에서 추가해야 합니다. 따라서 업데이트 손실 방지는 애플리케이션의 책임입니다.
"더티 읽기", "반복 불가능 읽기" 및 "팬텀 읽기"는 실제로 데이터베이스 읽기 일관성 문제이며 특정 트랜잭션 격리 메커니즘을 제공하는 데이터베이스로 해결해야 합니다.
One is locking: Lock 다른 트랜잭션이 데이터를 수정하는 것을 방지하기 위해 데이터를 읽기 전에 먼저 삭제합니다.
다른 하나는 다중 버전 데이터베이스라고도 알려진 데이터 다중 버전 동시성 제어(MVCC 또는 MCC)입니다. 잠금을 추가하지 않고 특정 메커니즘을 통해 데이터 요청 시점의 일관된 데이터 스냅샷이 생성됩니다. (스냅샷), 이 스냅샷을 사용하여 특정 수준(문 수준 또는 트랜잭션 수준)의 일관된 읽기를 제공합니다. 사용자의 관점에서 볼 때 데이터베이스는 동일한 데이터의 여러 버전을 제공할 수 있는 것으로 보입니다.
SQL 표준은 4가지 유형의 격리 수준을 정의합니다. 각 수준은 트랜잭션 내 및 트랜잭션 간에 표시되는 수정 사항과 보이지 않는 수정 사항을 지정합니다. 격리 수준이 낮을수록 일반적으로 더 높은 동시성을 지원하고 시스템 오버헤드가 더 낮습니다.
레벨 1: 커밋되지 않은 읽기(커밋되지 않은 콘텐츠 읽기)
레벨 2: Read Committed(제출된 콘텐츠 읽기)
이것은 대부분의 경우 기본 격리 레벨입니다. 데이터베이스 시스템(MySQL 기본값은 아님)
격리의 간단한 정의를 충족합니다. 트랜잭션은 커밋된 트랜잭션에 의해 변경된 내용만 볼 수 있습니다.
이 격리 수준의 문제점은 다음과 같습니다. - 반복 불가능 읽기: 반복 불가능 읽기는 다음을 의미합니다. 동일한 트랜잭션에서 똑같은 select 문을 실행하면 다른 결과가 나타날 수 있습니다. 이 상황의 가능한 이유는 다음과 같습니다.
새 커밋으로 인한 교차 트랜잭션이 있어 데이터가 변경됩니다.
데이터베이스가 여러 인스턴스에 의해 운영되는 경우 동일한 트랜잭션의 다른 인스턴스가 해당 인스턴스에 있습니다. 처리 중에 새로운 커밋이 발생할 수 있습니다
레벨 3: 반복 읽기(다시 읽기 가능)
다중 버전 동시성 제어:Mysql의 대부분의 트랜잭션 스토리지 엔진 구현은 단순한 행 수준 잠금이 아닙니다. 동시성 향상을 고려하여 Oracle, PostgreSQL 등 MVCC(다중 버전 동시성 제어)가 일반적으로 동시에 구현됩니다. 그러나 구현은 다양합니다.
MVCC는 특정 시점의 데이터 스냅샷을 저장하여 구현됩니다. 즉, 구현하는 데 아무리 오랜 시간이 걸리더라도 각 항목에서 표시되는 데이터는 일관됩니다.
낙관적 동시성 제어와 비관적 동시성 제어로 구분됩니다.
MVCC 작동 방식: InnoDB의 MVCC는 각 레코드 행 뒤에 두 개의 숨겨진 열을 저장하여 구현됩니다. 두 컬럼 중 하나는 행 생성 시간을 저장하고, 다른 하나는 행 만료 시간(삭제 시간)을 저장합니다. 물론 저장되는 것은 실시간이 아닌 시스템 버전 번호이다. 새로운 트랜잭션이 시작될 때마다 시스템 버전 번호가 자동으로 추가됩니다. 트랜잭션 시작 시 시스템 버전 번호는 트랜잭션 버전 번호로 사용되며, 비교를 위해 각 레코드 행의 버전 번호를 쿼리하는 데 사용됩니다.
REPEATABLE READ 격리 수준에서 MVCC가 작동하는 방식:InnoDB는 다음 조건에 따라 각 행 레코드를 확인합니다. INSERT DELETE UPDATE 레벨 4: 직렬화 가능가장 높은 격리 레벨입니다 격리 수준 비교 각 특정 데이터베이스가 반드시 위의 4가지 격리 수준을 완전히 구현하지는 않습니다. 예: 트랜잭션 로그트랜잭션 로그는 트랜잭션 효율성을 높이는 데 도움이 될 수 있습니다. 트랜잭션 로그를 사용하면 스토리지 엔진은 매번 수정된 데이터 자체를 디스크에 유지하는 대신 하드 디스크에 유지되는 트랜잭션 로그에 수정 동작을 복사한 다음 기록합니다. Mysql의 트랜잭션 구현 원리트랜잭션의 구현은 데이터베이스의 스토리지 엔진을 기반으로 합니다. 스토리지 엔진마다 트랜잭션 지원 수준이 다릅니다. mysql에서 트랜잭션을 지원하는 스토리지 엔진에는 innoDB와 NDB가 있습니다. 동시성 제어 事务的隔离性是通过锁实现,而事务的原子性、一致性和持久性则是通过事务日志实现。说到事务日志,不得不说的就是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支持本地事务的语句: 事务使用注意点: 自动提交(autocommit): InnoDB在事务执行过程中,使用两阶段锁协议: 随时都可以执行锁定,InnoDB会根据隔离级别在需要的时候自动加锁; 锁只有在执行commit或者rollback的时候才会释放,并且所有的锁都是在同一时刻被释放。 InnoDB也支持通过特定的语句进行显示锁定(存储引擎层): MySQL Server层的显示锁定: (更多阅读:MySQL锁总结) MySQL对分布式事务的支持 分布式事务的实现方式有很多,既可以采用innoDB提供的原生的事务支持,也可以采用消息队列来实现分布式事务的最终一致性。这里我们主要聊一下innoDB对分布式事务的支持。 MySQL 从 5.0.3 开始支持分布式事务,当前分布式事务只支持 InnoDB 存储引擎。一个分布式事务会涉及多个行动,这些行动本身是事务性的。所有行动都必须一起成功完成,或者一起被回滚。 如图,mysql的分布式事务模型。模型中分三块:应用程序(AP)、资源管理器(RM)、事务管理器(TM): 分布式事务采用两段式提交(two-phase commit)的方式: 分布式事务(XA 事务)的 SQL 语法主要包括: 虽然 MySQL 支持分布式事务,但是在测试过程中,还是发现存在一些问题: 如果分支事务在执行到 prepare 状态时,数据库异常,且不能再正常启动,需要使用备份和 binlog 来恢复数据,那么那些在 prepare 状态的分支事务因为并没有记录到 binlog,所以不能通过 binlog 进行恢复,在数据库恢复后,将丢失这部分的数据。 如果分支事务的客户端连接异常中止,那么数据库会自动回滚未完成的分支事务,如果此时分支事务已经执行到 prepare 状态, 那么这个分布式事务的其他分支可能已经成功提交,如果这个分支回滚,可能导致分布式事务的不完整,丢失部分分支事务的内容。
최대한 활용하려면 이 두 가지 버전 번호를 저장하세요. 작업을 잠글 필요가 없습니다. 이를 통해 데이터 작업이 단순해지고 성능이 향상되며 복잡한 요구 사항에 필요한 행만 읽혀집니다. 단점은 각 레코드 행에 추가 저장 공간, 더 많은 행 확인 및 추가 유지 관리 작업이 필요하다는 것입니다. MVCC는 COMMITTED READ(읽기 제출) 및 REPEATABLE READ(반복 읽기)의 두 가지 격리 수준에서만 작동합니다. MVCC는 행 수준 잠금의 변형으로 생각할 수 있지만 많은 경우 잠금 작업을 피하고 오버헤드가 낮습니다. 다양한 데이터베이스의 구현 메커니즘은 다르지만 대부분은 비차단 읽기 작업을 구현하고(읽기에는 잠금이 필요하지 않으며 반복 불가능한 읽기 및 팬텀 읽기는 피할 수 있음) 쓰기 작업은 필요한 행만 잠급니다(쓰기는 반드시 필요함). 잠김) 그렇지 않으면 다른 트랜잭션에 의한 동시 쓰기로 인해 데이터 불일치가 발생합니다.
트랜잭션이 서로 충돌하지 않도록 강제로 주문하여 팬텀 읽기 문제를 해결합니다. 즉, 읽은 각 데이터 행에 공유 잠금을 추가합니다. MySQL 잠금 요약
트랜잭션 로그는 추가 방식을 사용하므로 로그 쓰기 작업은 디스크의 여러 위치에서 헤드를 이동해야 하는 임의 I/O와 달리 디스크의 작은 영역에서 순차적 I/O이므로 트랜잭션이 사용됩니다. 로깅 방법이 상대적으로 훨씬 빠릅니다.
START TRANSACTION | BEGIN [WORK] COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE] ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE] SET AUTOCOMMIT = {0 | 1}
tables 被执行。
务类型的表进行特别的处理,因为 COMMIT、ROLLBACK 只能对事务类型的表进行提交和回滚。
不同的 SAVEPOINT。需要注意的是,如果定义了相同名字的 SAVEPOINT,则后面定义的SAVEPOINT 会覆盖之前的定义。对于不再需要使用的 SAVEPOINT,可以通过 RELEASE SAVEPOINT 命令删除 SAVEPOINT, 删除后的 SAVEPOINT, 不能再执行 ROLLBACK TO SAVEPOINT命令。
Mysql默认采用自动提交模式,可以通过设置autocommit变量来启用或禁用自动提交模式select ... lock in share mode //共享锁 select ... for update //排他锁
lock table和unlock table
XA {START|BEGIN} xid [JOIN|RESUME]
如果分支事务在达到 prepare 状态时,数据库异常重新启动,服务器重新启动以后,可以继续对分支事务进行提交或者回滚得操作,但是提交的事务没有写 binlog,存在一定的隐患,可能导致使用 binlog 恢复丢失部分数据。如果存在复制的数据库,则有可能导致主从数据库的数据不一致。
总之, MySQL 的分布式事务还存在比较严重的缺陷, 在数据库或者应用异常的情况下,
可能会导致分布式事务的不完整。如果应用对于数据的完整性要求不是很高,则可以考虑使
用。如果应用对事务的完整性有比较高的要求,那么对于当前的版本,则不推荐使用分布式
事务。
위 내용은 데이터베이스 트랜잭션 및 MySQL 트랜잭션 요약의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!