Redisのトランザクションの詳細な分析と使用

非常に重要な基本的な機能で、リレーショナル・データベースとして - トランザクション、Redisの中で処理して使用する方法ですか?

1.はじめに

トランザクションは、複数のコマンド包装、実行使い捨てメカニズムを順次提供し、サーバが唯一のトランザクション内のすべてのコマンドが完了した後、他のコマンドにこのクライアントを処理し続けることを確実にするためです。
総務なく、他のリレーショナル・データベースに、非常に重要な機能が不可欠です。支払うためにシーンに、例えば、唯一の通常の状況下で、通常の消費が終了した後、唯一の口座残高マイナス。しかし、保証はトランザクションがない場合、消費者は、失敗した発生することがありますが、まだ控除されるようにバランスを占めることになる、と私は、この場合には、誰がそれを受け入れることができないことであるべきだと思いますか?そのため、取引は非常に重要な基本的な機能でリレーショナルデータベースです。

2.基本的な事柄

他の言語でのサービスは、一般的に行われる処理は、3つのフェーズに分割されています。

  • オープン総務--BEGINトランザクション
  • ビジネスコードの実行、トランザクションがコミットされたトランザクション--Common
  • 異常な、--Rollbackトランザクション処理のビジネスが表示されたトランザクションをロールバック

一例として、トランザクションを実行するためのJava:

// 开启事务
begin();
try {
    //......
    // 提交事务
    commit();
} catch(Exception e) {
    // 回滚事务
    rollback();
}

開始から終了までの取引でRedisのは、三つの段階を通過することです。

  • オープン情勢
  • コラムへのコマンド
  • 執行部は、/トランザクションをアボート

その中でも、オープントランザクションを使用するmulti コマンドは、トランザクションが使用して行わexec 使ってトランザクションを放棄するコマンドをdiscard コマンドを使用します。

1)オープン情勢

multi 次のようにトランザクションコードを有効にするコマンドは以下のとおりです。

> multi
OK

multi :コマンドは、状態は以下に示すように、トランザクションモードになり、非トランザクションモード状態からクライアントを可能に
image.png
注意してください実行した場合は、トランザクションを開いた場合、マルチコマンドは入れ子にすることはできない、と:multi次のエラーを促すメッセージが表示されますコマンドを:

(エラー)ERR MULTIコールは入れ子にすることはできません

結果の実装は、次のコードに示すように:

127.0.0.1:6379> multi
OK
127.0.0.1:6379> multi
(error) ERR MULTI calls can not be nested

非クライアントトランザクションの状態は、使用する場合はmulti 、コマンドを、クライアントが結果を返しOK 、クライアントは、トランザクション状態を有する場合、次に実行  multi コマンドmulti コマンドエラーをネストすることはできないが、以下に示すように、クライアントは、トランザクション状態を終了しませんそれは示しています。
image.png

2)コマンド・エンキュー

クライアントは、事務の状態になった後、すべての日常業務Redisのコマンドの実行は、(非実行またはあきらめ、列コマンドに例外を発生させたトランザクションをトリガ)、カラム内に成功したコマンドが戻った後、カラムをオンにしますQUEUED 次のコードに示すように、:

> multi
OK
> set k v
QUEUED
> get k
QUEUED

以下に示すように実行フロー:
image.png
:列アクセスコマンドFIFO順(FIFO)を、トランザクションが順次前後からエンキューコマンドの順序に従うこと。

3)執行部/放棄総務

コマンドが取引をされ実行されexec たトランザクションのコマンドを放棄しますdiscard 。
以下のように実行サンプルコードトランザクション:

> multi
OK
> set k v2
QUEUED
> exec
1) OK
> get k
"v2"

次のようにトランザクションを放棄するサンプルコード:

> multi
OK
> set k v3
QUEUED
> discard
OK
> get k
"v2"

実行フローは下記のように:
image.png

3.ロールバックトランザクションエラー&

トランザクション実行エラーは、次の3つのカテゴリに分類されます。

  • ;実行時に発生するエラー(実行エラーと呼びます)
  • ときにエラーカラムは、トランザクション全体を終了していません。
  • 場合は、列エラーが全体のトランザクションをアボートします。

    1)場合、実行エラー

    次のようにサンプル・コードは次のとおりです。
> get k
"v"
> multi
OK
> set k v2
QUEUED
> expire k 10s
QUEUED
> exec
1) OK
2) (error) ERR value is not an integer or out of range
> get k
"v2"

:実行は、次のように説明した
image.png
トランザクションがキュー内のすべてのコマンドを実行して終了するまでトランザクションは、トランザクションが進行し、コマンドの実行中にエラーが発生したキュー場合でも、上記の結果からわかるように。

2)カラムエラーにトランザクションの終了を引き起こし

次のようにサンプル・コードは次のとおりです。

> get k
"v"
> multi
OK
> set k v2
QUEUED
> multi
(error) ERR MULTI calls can not be nested
> exec
1) OK
> get k
"v2"

次に示すコマンドインタプリタ実行します。
image.png
見て分かるように、繰り返し実行はmulti 間違った列につながるが、トランザクションを終了していないが、最終的にクエリの結果は、取引の成功に実行されます。また繰り返すmulti のコマンドを、だけでなく、事務の状態で行うwatch と同じ効果で、以下は約詳細に説明しますwatch コンテンツ。

3)列エラーにトランザクションの終了を引き起こすことはありません。

次のようにサンプル・コードは次のとおりです。

> get k
"v2"
> multi
OK
> set k v3
QUEUED
> set k
(error) ERR wrong number of arguments for 'set' command
> exec
(error) EXECABORT Transaction discarded because of previous errors.
> get k
"v2"

以下のようにファイル名を指定して実行を説明します:
image.png

4)なぜ、トランザクション・ロールバックをサポートしていませんか?

Redis 官方文档的解释如下:

If you have a relational databases background, the fact that Redis commands can fail during a transaction, but still Redis will execute the rest of the transaction instead of rolling back, may look odd to you.
However there are good opinions for this behavior:

  • Redis commands can fail only if called with a wrong syntax (and the problem is not detectable during the command queueing), or against keys holding the wrong data type: this means that in practical terms a failing command is the result of a programming errors, and a kind of error that is very likely to be detected during development, and not in production.
  • Redis is internally simplified and faster because it does not need the ability to roll back.

An argument against Redis point of view is that bugs happen, however it should be noted that in general the roll back does not save you from programming errors. For instance if a query increments a key by 2 instead of 1, or increments the wrong key, there is no way for a rollback mechanism to help. Given that no one can save the programmer from his or her errors, and that the kind of errors required for a Redis command to fail are unlikely to enter in production, we selected the simpler and faster approach of not supporting roll backs on errors.

大概的意思是,作者不支持事务回滚的原因有以下两个:

  • 他认为 Redis 事务的执行时,错误通常都是编程错误造成的,这种错误通常只会出现在开发环境中,而很少会在实际的生产环境中出现,所以他认为没有必要为 Redis 开发事务回滚功能;
  • 不支持事务回滚是因为这种复杂的功能和 Redis 追求的简单高效的设计主旨不符合。

这里不支持事务回滚,指的是不支持运行时错误的事务回滚。

4.监控

watch 命令用于客户端并发情况下,为事务提供一个乐观锁(CAS,Check And Set),也就是可以用 watch 命令来监控一个或多个变量,如果在事务的过程中,某个监控项被修改了,那么整个事务就会终止执行
watch 基本语法如下:

watch key [key ...]

watch 示例代码如下:

> watch k
OK
> multi
OK
> set k v2
QUEUED
> exec
(nil)
> get k
"v"

从以上命令可以看出,如果 exec 返回的结果是 nil 时,表示 watch 监控的对象在事务执行的过程中被修改了。从 get k 的结果也可以看出,在事务中设置的值 set k v2 并未正常执行。
执行流程如下图所示:
image.png
注意watch 命令只能在客户端开启事务之前执行,在事务中执行 watch 命令会引发错误,但不会造成整个事务失败,如下代码所示:

> multi
OK
> set k v3
QUEUED
> watch k
(error) ERR WATCH inside MULTI is not allowed
> exec
1) OK
> get k
"v3"

执行命令解释如下图所示:
image.png
unwatch 命令用于清除所有之前监控的所有对象(键值对)。
unwatch 示例如下所示:

> set k v
OK
> watch k
OK
> multi
OK
> unwatch
QUEUED
> set k v2
QUEUED
> exec
1) OK
2) OK
> get k
"v2"

可以看出,即使在事务的执行过程中,k 值被修改了,因为调用了 unwatch 命令,整个事务依然会顺利执行。

5.事务在程序中使用

以下是事务在 Java 中的使用,代码如下:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

public class TransactionExample {
    public static void main(String[] args) {
        // 创建 Redis 连接
        Jedis jedis = new Jedis("xxx.xxx.xxx.xxx", 6379);
        // 设置 Redis 密码
        jedis.auth("xxx");
        // 设置键值
        jedis.set("k", "v");
        // 开启监视 watch
        jedis.watch("k");
        // 开始事务
        Transaction tx = jedis.multi();
        // 命令入列
        tx.set("k", "v2");
        // 执行事务
        tx.exec();
        System.out.println(jedis.get("k"));
        jedis.close();
    }
}

6.小结

事务为多个命令提供一次性按顺序执行的机制,与 Redis 事务相关的命令有以下五个:

  • multi:开启事务
  • exec:执行事务
  • discard:丢弃事务
  • watch:为事务提供乐观锁实现
  • unwatch:取消监控(取消事务中的乐观锁)

Redisの取引は、通常の状況下では3つのフェーズに分かれています、業務を回しコラム、執行部を命じます。Redisのトランザクションは、誤ったトランザクションのロールバック操作をサポートしていますが、エラーの列の一部として、しないset keyか、watch監視項目は、トランザクション全体のロールバック機能を提供するように変更されたとき。

7.質問

Redisのトランザクションの問題を解決する方法の同時変更?Redisのトランザクションのロールバックをサポートそれ?Redisのトランザクションを使用した場合、どの3つのエラーが発生?これらの3つのエラー情勢の影響は何ですか?唯一の専門家が質問に答えることができ、あなたはいくつかのそれに答えることができますか?

8.リファレンス&謝辞

https://redis.io/topics/transactions

https://redisbook.readthedocs.io/en/latest/feature/transaction.html#id3

おすすめ

転載: www.cnblogs.com/vipstone/p/11755496.html