取引のためのドキュメントは言う:「私たちは廃止し、最終的に取引を削除することができる」とRedis:なぜLuaスクリプトはトランザクションを置き換えますか?
は
http://redis.io/topics/transactionsを「あなたは はRedisのトランザクションでできることのすべてを、あなたはまた、スクリプトを使って行うことができます」
しかし、それはありますか?私はこれに問題があると思う。
トランザクション内では、複数の変数を監視し、それらの変数を読み込み、それらの変数の一意の状態に基づいて、EXECを呼び出す前に完全に異なる書き込みセットを作成できます。介入時に何かがそれらの変数の状態に干渉すると、EXECはトランザクションを実行しません。 (再試行することができます。これは完璧な取引システムです)。
エバールスクリプトではできません。このページのドキュメントによると:。
「純粋な関数などのスクリプト...スクリプトは常に同じ Redisのは、同じ入力データ セット与えられた同じ引数でコマンドを記述したスクリプトの動作ができないと評価します(非明示的)の情報や状態は、スクリプト の実行が進むにつれて変わる可能性があります。または、 はI/Oデバイスからの外部入力に依存しません。
私がEVALで見る問題は、スクリプトの内部にこれらの変数の状態を取得し、それらの変数の状態に基づいて、書き込みのユニークなセットを作ることができないということです。繰り返しますが、「同じ入力データ・セットの場合、スクリプトは常に同じ引数を持つ同じRedis書き込みコマンドを評価します。したがって、結果の書き込みはすでに決定されており(最初の実行からキャッシュされます)、EVALスクリプトはGET値がスクリプトの内部にあるかどうかを気にしません。 EVALを呼び出す前にこれらの変数に対してGETを実行し、EVALスクリプトにそれらの変数を渡すだけですが、ここでは問題があります:GETを呼び出すこととEVALを呼び出すことの間に原子性の問題があります。
つまり、EVALの場合は、これらの変数を取得してEVALスクリプトに渡す必要がある、つまり、トランザクションのためにWATCHを実行したすべての変数。実際にスクリプトが開始されるまで、スクリプトのアトミック性は保証されていないので、スクリプトを開始するためにEVALを呼び出す前にこれらの変数を取得する必要があるため、変数の状態がGETとパスEVALにしたがって、非常に重要なユースケースについては、EVALを使用しているわけではありません。
重要なRedisの機能が失われるとトランザクションが非推奨になってしまうのはなぜですか?または、私がまだ理解していないEVALスクリプトでこれを行う方法が実際にありますか?または、EVALのためにこれを解決できる機能が計画されていますか? (仮説的な例:もしWATCHがEVATと同じようにEVATを使ってWATCHを動作させたのであれば、それはうまくいくかもしれません)
これには解決策がありますか?あるいは、私はレディスが長期的に完全な取引で安全でないかもしれないことを理解していますか?
あなたの言うことが実践的な経験に基づいているなら、それは良いことです!それはドキュメントの私の解釈よりも優先されます: "スクリプトは常に、同じ入力データセットで同じ引数を持つ同じRedis書き込みコマンドを評価します。私にとって、これは、スクリプトが2度目で評価されないように、キャッシュ機構が存在することを意味します。同じ入力を与えられた一連の書き込みを想定しているだけです。決定的には聞こえません。しかし、あなたが実際にこの経験をしていれば、私はあなたの専門知識を延期し、あなたの答えに感謝します。 – OCDev
また、私の仮説的な例については、EVATが実行され、* EVALが実行される前に* WATCHが使用できる仮想的な機能について話していました。 (この意味でEVALがEXECのような振る舞いをする新しい機能)このようにして、GETはEVALに渡し、変更を心配する必要はありません。 (EVALの内部が結局は決定論的であるにもかかわらず、MUTポイント。)もう一度ありがとう。 :) – OCDev
Redis DB Serverがトランザクション(MULTI/EXEC)とEvalの間に落ちるとどうなりますか? POP/PUSHのようなコマンドはほとんど実行されていないと思っています。 –