Mysql でのトランザクション処理の詳細な紹介

黄舟
リリース: 2017-08-20 15:41:24
オリジナル
1509 人が閲覧しました

トランザクション処理とは何ですか? ?トランザクション処理は、データベースの整合性を維持するために使用され、MySQL 操作のバッチが完全に実行されるか、実行されないかが保証されます。

1. MySQL トランザクションの概念

MySQL トランザクションは主に、大規模な操作と高度な複雑性を伴うデータの処理に使用されます。論理実行ユニットは、1 つまたは複数のデータベース操作シーケンスで構成されます。この一連の操作は完全に実行されるか、すべての実行が中止されます。 MySQL では、Innodb データベース エンジンを使用するデータベースまたはテーブルのみがトランザクションをサポートします。トランザクションは、挿入、更新、および削除ステートメントを管理するために使用されます。

2. トランザクション特性: アトミシティ (原子性)、一貫性 (安定性、一貫性)、分離性 (分離)、および耐久性 (継続性、信頼性)。これら 4 つのプロパティは、ACID プロパティとも呼ばれます。

1. 原子性: アトムが自然界の最小の粒子であり、分割できないという特性があるのと同じように、トランザクションはアプリケーション内の最小の実行単位です。トランザクションは、アプリケーション内で分割できない最小の論理的な実行本体であり、トランザクションのグループは成功することも、取り消されることもあります。

2. 安定性と一貫性: トランザクション実行の結果、データベースはある一貫性状態から別の一貫性状態に変化する必要があります。データベースには、正常にコミットされたトランザクションの結果のみが含まれている場合、一貫性のある状態になります。一貫性はアトミック性によって保証されます。不正なデータ(外部キー制約等)があり、トランザクションが取り消されました。

3. 分離: 各トランザクションの実行は相互に干渉しません。トランザクションの内部操作は他の同時トランザクションから分離されます。つまり、同時に実行されるトランザクションは互いの中間状態を確認できず、同時に実行されるトランザクションは相互に影響を与えることができません。トランザクションは独立して実行されます。ある取引の結果が他の取引に影響を与える場合、他の取引は撤回されます。トランザクションを 100% 分離するには、速度を犠牲にする必要があります。

4. 継続性、信頼性: 耐久性とも呼ばれる継続性は、トランザクションが送信されると、データに加えられた変更は永続的なストレージ (通常は物理データベース) に記録されなければならないことを意味します。ソフトウェアまたはハードウェアがクラッシュすると、InnoDB データ テーブル ドライバーはログ ファイルを使用してログ ファイルを再構築し、変更します。信頼性と高速性は両立しません。innodb_flush_log_at_trx_commit オプションは、トランザクションをログに保存するタイミングを決定します。

注: ストレージ エンジン MyISAM はトランザクションをサポートしませんが、ストレージ エンジン InnoDB はトランザクションをサポートします。トランザクションは、データに影響を与えるステートメントに対してのみ有効です。 show Engines mysql ロックでサポートされているデータ エンジンを表示します。

3. データ読み取りの概念

1. ダーティ リード: いわゆるダーティ リードはダーティ データの読み取りであり、ダーティ データはコミットされていないデータを指します。トランザクションはレコードを変更しています。トランザクションが完了してコミットされるまで、データは保留状態になります (コミットまたはロールバックされる可能性があります)。この時点では、2 番目のトランザクションがコミットされていないデータを読み取り、これに基づいてさらなる処理を行います。コミットされていないデータの依存関係が生成されます。この現象をダーティリーディングと呼びます。

2. 非反復読み取り: トランザクションは同じレコードを連続して読み取りますが、2 回読み取られるデータは異なります。これを非反復読み取りと呼びます。つまり、このトランザクションの 2 つの読み取りの間に、他のトランザクションによってデータが変更されました。

3. ファントムリード: トランザクションが同じクエリ条件に従って以前に取得したデータを再度読み取ると、他のトランザクションがそのクエリ条件を満たす新しいデータを挿入したことが判明するこの現象はファントムリードと呼ばれます。

4. トランザクション分離レベル

トランザクション分離レベルの構文を変更します:

SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}
ログイン後にコピー

1. Read Uncommitted (未承認読み取り、未コミット読み取り): これは最も低い分離レベルであり、他のトランザクションは、トランザクション分離レベルが存在しないことを確認できます。提出 データ。このレベルはダーティ リードにつながる可能性があります。トランザクションがデータの書き込みを開始した場合、別のトランザクションが同時にデータを書き込むことはできませんが、他のトランザクションはこのデータ行を読み取ることができます。この分離レベルは、「排他的書き込みロック」によって実現できます。更新の損失は回避されますが、ダーティ リードが発生する可能性があります。つまり、トランザクション B はトランザクション A のコミットされていないデータを読み取りました。 SELECT ステートメントは非ロック方式で実行されるため、ダーティ データが読み取られる可能性があり、分離レベルは最も低くなります。


SET session transaction isolation level read uncommitted ;
SET global transaction isolation level read uncommitted;/*全局建议不用*/
SELECT @@global.tx_isolation;
SELECT @@session.tx_isolation;
SELECT @@tx_isolation;
ログイン後にコピー

単純な Student テーブルを作成し、ID、名前、および num フィールドを設定し、トランザクション 1 を開始し、ストアド プロシージャを介して新しいテーブルをテーブルに追加します。トランザクションは送信されません。現在のデータベース トランザクション ステータスを確認します。 , データトランザクションが表示されます。トランザクション レベルは READ UNCOMMITTED:


drop table if exists student;
create table student(
id int primary key auto_increment comment 'id',
name varchar(100) comment '名称',
num int
);
drop procedure if exists proc_on_sw;
delimiter ;;
create procedure proc_on_sw()
begin
start transaction;
insert into student(name,num) value('aaa',1);
select * from information_schema.INNODB_TRX;
end
;;
delimiter ;;
call proc_on_sw();
ログイン後にコピー

新しいトランザクション 2 を作成し、Student テーブルをクエリします。 READ UNCOMMITTED レベルでは、他のトランザクションのコミットされていないデータを確認できます。データベースのトランザクション ステータスを再度確認すると、ステータスが正常であることがわかります。


start transaction ;
select * from student;
commit;
select * from information_schema.INNODB_TRX;
ログイン後にコピー

2. Read Committed (authorized read、read commit): データを読み取るトランザクションは、他のトランザクションがデータの行にアクセスし続けることを許可しますが、コミットされていない書き込みトランザクションは、他のトランザクションがその行にアクセスすることを禁止します。この分離レベルではダーティ読み取りは回避されますが、反復不可能な読み取りが発生する可能性があります。トランザクション A が事前にデータを読み取り、トランザクション B がデータを更新してトランザクションをコミットし、トランザクション A が再度データを読み取ると、データは変更されています。


SET session transaction isolation level read committed ;
SET global transaction isolation level read committed; /*全局建议不用*/

drop procedure if exists proc_on_up;
delimiter ;;
create procedure proc_on_up()
begin
set autocommit=0;
update student set name='cc' where id=1;
commit;
set autocommit=1;
end
;;
delimiter ;;
call proc_on_up();
select * from student;
ログイン後にコピー


  3.repeatable read(可重复读取):就是在开始读取数据(事务开启)时,不再允许修改操作,事务开启,不允许其他事务的UPDATE修改操作,不可重复读对应的是修改,即UPDATE操作。但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作,而不是UPDATE操作。避免了不可重复读取和脏读,但是有时可能出现幻读。这可以通过“共享读锁”和“排他写锁”实现。

set session transaction isolation level repeatable read;
ログイン後にコピー

  4.串行化、序列化:提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。序列化是最高的事务隔离级别,同时代价也花费最高,性能很低,一般很少使用,在该级别下,事务顺序执行,不仅可以避免脏读、不可重复读,还避免了幻像读。

set session transaction isolation level serializable;
ログイン後にコピー

      隔离等级   脏读   不可重复读   幻读
      读未提交   YES   YES      YES
      读已提交   NO    YES      YES
      可重复读   NO    NO      YES
      串行化    NO    NO       NO

五、完整例子包括提交和回滚完整例子


drop procedure if exists pro_new;
delimiter;;
create procedure pro_new(out rtn int)
begin
declare err INT default 0;
-- 如果出现异常,会自动处理并rollback
declare exit handler for sqlexception ROLLBACK ; 
-- 启动事务
set autocommit=0;
start transaction;
insert into student(name,num) values(NULL,2.3);
-- set err = @@IDENTITY; -- =  获取上一次插入的自增ID;
set err =last_insert_id(); -- 获取上一次插入的自增ID
insert into student(name,num) VALUEs('ccc',err);
-- 运行没有异常,提交事务
commit;
-- 设置返回值为1
set rtn=1;
set autocommit=1;
end
;;
delimiter ;;
set @n=1;
call pro_new(@n);
select @n;
ログイン後にコピー

以上がMysql でのトランザクション処理の詳細な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!