トランザクションの4つの特徴
- 原子性トランザクションの実行に失敗すると、ロールバックする必要があるとよく言われますが、実際には、これはトランザクションの原子性、完全なトランザクション、成功のいずれかのすべての実装では、1つまたは複数の障害が発生した場合、ロールバックする必要があります、実際には、これは一貫性の基礎となる別の特性です。
- 整合性整合性、まず栗、栗を理解する最も簡単なのは、もともと劉備は200元を持って、関羽はお金を持っていない、その後、劉備は関羽に100元を転送し、今、あなたはこの操作を実行するために2つの手順が必要です、まず100元のアカウント内の劉備を引く、2番目のステップは、関羽のアカウントに100元の量を増やすには、これらの2つのステップは、トランザクションと見なされます。取引前、関羽0 + 劉備200 = 200元、取引後、関羽100 + 劉備100 = 200、データは平坦に増減しませんでした。そして、兄弟がどのように変わっても、この合計は変わりません、これは取引の一貫性です。一貫性とは、トランザクションが一貫性のある状態からデータベースを使用して、別の一貫性のある状態に変換する必要があります。最初の原子性について考えて、半分が成功し、半分が失敗し、ロールバックしない場合は、データの一貫性があるでしょうか?
- 分離分離は、主に同時アクセスのため、複数のユーザーがデータテーブルを変更すると、トランザクションを開くには、各ユーザのためのデータベースは、他のトランザクションによって干渉することはできません、複数の同時実行は、お互いを分離するために、つまり、同じリソースのために、同じ期間内にトランザクションを変更することができます。
- 永続性 永続性とは、トランザクションが正常にコミットされると、その変更がデータベースに対して永続することを意味します。
トランザクションの分離レベル
mysql では 4 つの分離レベル、すなわち ru、rc、rr、serializealbe がサポートされています。
READ UNCOMMITTED
未コミット
つまり、あるトランザクションの実行が完了していない場合、そのデータは他のトランザクションからも見えており、変更されたもののまだコミットされていないデータを読み取ることができるため、データの正確性を保証しないこのような分離レベルはほとんど必要ないということです。そのため、パフォーマンスも最適になります。
- 関連データベースとデータテーブルの作成
create schema test;
use test;
CREATE TABLE `t` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`point` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
貼り付け次のSQLステートメントは、右の実装の後に最初の左の同じ行のコードは、2つのSQLウィンドウで実行されることに注意してください、6行目の実装では、console2は、トランザクションを開いたが、まだコミットされていないことがわかったが、console1は、コミットされていないの結果を照会されています。これは、コミットされていない読み取られます
READ COMMITTED ほとんどのデータベースのデフォルトの分離レベルはrcであり、つまり、トランザクションは、コミットされていない場合、唯一の元の結果を参照してください、コミットされている変更の結果を見ることができ、コミットされていない結果の変更の結果は表示されませんが、これは問題がある、何が問題なのでしょうか?つまり、トランザクションでは、別のトランザクションがデータを変更し、同じクエリの最初のトランザクションでは、送信する場合、それは2つの異なるデータ、つまり、非再現性の読み取りをクエリします!
新しいエントリーが提出されないと、そのエントリーは読まれません。
このとき、2つのウィンドウが同時に1つのデータに変更を加えるとどうなるでしょうか。2つ目の更新コマンドは1つ目のコマンドがコミットするまで待ちます。
REPEATABLE READ REPEATABLE READはmysqlのデフォルトの分離レベルであり、rrはダーティ・リードの問題を解決しますが、ファントム・リードが発生する可能性があります。
解決されたread-uncommittedとunrepeatable readを見てみましょう。
ファントムリードは、実は繰り返し不可能なリードの欠点に対する解決策です。第一に、トランザクション1はすでにid3を追加するインサートオペレーションを実行していますが、反復可能なリードのために、トランザクション2は追加されたデータを見ません。繰り返し読み取りは、ある時点のデータのスナップショットをキャッシュに書き込むようなものです。
SERIALIZABLE
実際には、まず自分の考えることができる、どのように繰り返される読み取りを解決するためにも、ファントムリードを解決できますか?しかし、以前の操作は、2つのトランザクションに基づいていますが、そのような2つのトランザクションとして、それに関連付けられ、それが解決されていない、シリアライズの意味である、ダーティリード、ファントムリード、繰り返し読み取りなどの問題を解決するためにシリアライズすることができますが、必然的に "シリアライズすることができます "の効率に影響を与えるので、ロック上のデータの各行の読み取りになりますので、ロックの待機時間とタイムアウトの問題の多くにつながる可能性があります。serialisable "は、ロック上のデータの各行を読み取るので、ロック待ちやタイムアウトの問題が大量に発生する可能性がありますので、実際の生産環境ではほとんどこの分離レベルを使用しませんので、データの一貫性を確保するために非常に必要なカットは、ケースの並行性の欠如を受け入れることができます唯一の分離のこのレベルの使用を検討する。
- デモンストレーションです。
- シリアライズを実現する方法は、少し意地悪なことを言うと、今回はキャッシュスナップショットではなく、リアルタイムのデータを読み取ることができますが、私はあなたに停止を与える更新操作。私はあなたがこの書き込み操作を実行させる前に、トランザクションが存在しないか、または他のトランザクションがコミットされるまで待つことができ、まあ、それだけです。これだけです。
- シリアライズを実現する方法は、少し意地悪なことを言うと、今回はキャッシュスナップショットではなく、リアルタイムのデータを読み取ることができますが、私はあなたに停止を与える更新操作。私はあなたがこの書き込み操作を実行させる前に、トランザクションが存在しないか、または他のトランザクションがコミットされるまで待つことができ、まあ、それだけです。これだけです。
- ロックでは、誰かがまた、ロックを読み取り、誰かがまた、ロックを書き込み、効率が影響を与えることができない、読み取りロックがあるかどうかを確認するために最初に書き込み、待機中にロックを読み取ります。この方法は簡単です。
- 包括的なダウン、または別の分離レベルを選択するビジネスシナリオの使用を見て、私は個人的にビジネスや使用rcのほとんどの方が良いと感じています。あなたはどう思いますか?SQLスクリプトコンソール1.sqlと
use test;
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
#READ UNCOMMITTED
start transaction ;
select * from t where id =1;
update t set point=50 where id =1;
commit ;
#READ COMMITTED
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
select * from t where id =1;
start transaction ;
update t set point=80 where id =1;
insert into t values (null,200);
select * from t where id =2;
commit ;
#REPEATABLE READ
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ ;
select * from t ;
start transaction ;
update t set point=100 where id=1;
commit ;
start transaction ;
select * from t ;
insert into t values (null,300);
select * from t ;
commit
## SERIALIZABLE
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE ;
start transaction ;
select * from t;
insert into t values (null,123);
コンソール2.sql
use test;
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
#READ UNCOMMITTED
start transaction ;
select * from t where id =1;
select * from t where id =1;
commit ;
#READ COMMITTED
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
select * from t where id =1;
start transaction ;
update t set point=10 where id =1;
select * from t where id =1;
select * from t where id =2;
commit ;
#REPEATABLE READ
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ ;
select * from t ;
start transaction ;
select * from t where id=1;
select * from t where id=1;
start transaction ;
select * from t ;
select * from t ;
insert into t values (3,300);
commit
## SERIALIZABLE
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE ;
start transaction ;
select * from t
commit;
この記事は、マルチ記事出版プラットフォーム自動出版されました。