redis分散ロック
2902 ワード
自分が作ったプロジェクトは支払いシステムなので、第三者が支払ったものを呼び出して、会社が使っているのはredis分布式ロックで、プロジェクトで使っているのがredisロックであることを最初から知り、今までこのredisロックに関する文章を書きたいと思っていましたが、半年も差がありませんでした.この過程も時間があって見て、断続的に、今書いても、プロジェクトでのロックがどのように実現されているのかを完全に理解していませんが、この過程でredisロックについて大まかな理解がありました.こちらの文章はあまり参考価値がなくて、ただ自分がプロジェクトの中で出会った问题だけで、私のbossも私に答えてくれなくて、私は间接的になぜか知りたいです.bossはただ私にもし本当に问题があれば、生成环境はとっくに问题があって、问题はありません.
質問:
コードの中でtestNgを実行して走る時keyによってredisの上でkeyにlongタイプのタイムスタンプを割り当てて、支払う時に鍵をかけて、最後にfinallyを実行する時、ロックを解放して、delコマンドを実行して、しかし実行し終わってから対応するkeyが削除されていないことを見て、コードが前のタイムスタンプが設定したタイムスタンプより小さいと判断して満足しない(どうして現在のタイムスタンプ+5000*2+1の赤字部分)コードは以下の通りです:
ちなみにロック解除のコードもshowします.
この文章は続けて書きます:以前ずっと理解していないシーン、テストの時に1つのシーンを発見して、支払いが終わった後に上流のシステムに戻って、明確な微信の支払いが失敗したことがあって、しかしクライアントはエラーを報告して(redisロックの問題を提示します)、問題が現れたシーンは私にどんなシーンだと推測されて、支払いの時に上流のシステムは戻りの結果がタイムアウトすることを受け入れていないで、それから上流のシステムは引き続きポーリングを調整して、この時ポーリングはredisロックに戻っ私はずっと問題があることを疑っています(私が地元で走っている間にロックが削除されていません.理論的には削除すべきですが、何の問題がありますか?)この問題を再現した後、最初の時間に顧客RedisDesktopManagerを通じてロックが削除されたかどうかを確認し、この時に削除されたかどうかを見て、bossに聞いて、bossの意味は上流システムがこの時タイムアウトしたので、すぐにポーリング(支払いとポーリングは同じロックである)を調整して、この時に支払いがまだ処理されていないので、クライアントredisロックに戻るすべての問題は、私の前の疑問を説明することができます.
度娘はredisロックの実現について、多くの方法があって、最近redisのpdfを1編過ぎたため、一度研究したいと思って、度娘はスクリプトの方式を使ってredis分布式ロックを実現することを見て、ただ1回スキャンして、表現したいのはredis分布式ロックを実現するのは多くの実現方式があって、必ずしもこのような方式を使う必要はありません
标红的部分有人理解的请留言告知,ありがとうございます!
質問:
コードの中でtestNgを実行して走る時keyによってredisの上でkeyにlongタイプのタイムスタンプを割り当てて、支払う時に鍵をかけて、最後にfinallyを実行する時、ロックを解放して、delコマンドを実行して、しかし実行し終わってから対応するkeyが削除されていないことを見て、コードが前のタイムスタンプが設定したタイムスタンプより小さいと判断して満足しない(どうして現在のタイムスタンプ+5000*2+1の赤字部分)コードは以下の通りです:
private boolean acquireLock(long lockTime) {
long lockTimeOut = lockTime * 2L;
long expiretime = System.currentTimeMillis() + lockTimeOut + 1L;
Long value = this.redisCacheUtils.setnx(this.key, String.valueOf(expiretime));
if(value != null && value.longValue() == 1L) {
this.locked = true;
return this.locked;
} else {
String curLockTimeStr = this.redisCacheUtils.get(this.key);
if(StringUtils.isEmpty(curLockTimeStr) || System.currentTimeMillis() > Long.valueOf(curLockTimeStr).longValue()) {
expiretime = System.currentTimeMillis() + lockTimeOut + 1L;
curLockTimeStr = this.redisCacheUtils.getSet(this.key, String.valueOf(expiretime));
if(StringUtils.isBlank(curLockTimeStr) || System.currentTimeMillis() > Long.valueOf(curLockTimeStr).longValue()) {
this.locked = true;
return this.locked;
}
}
return false;
}
}
ちなみにロック解除のコードもshowします.
public void unlock() {
try {
if(this.locked) {
String curLockTimeStr = this.redisCacheUtils.get(this.key);
if(StringUtils.isNotEmpty(curLockTimeStr) && System.currentTimeMillis() <= Long.valueOf(curLockTimeStr).longValue()) {
this.redisCacheUtils.del(this.key);
}
}
} catch (Exception var2) {
this.logger.logException(var2);
}
}
この文章は続けて書きます:以前ずっと理解していないシーン、テストの時に1つのシーンを発見して、支払いが終わった後に上流のシステムに戻って、明確な微信の支払いが失敗したことがあって、しかしクライアントはエラーを報告して(redisロックの問題を提示します)、問題が現れたシーンは私にどんなシーンだと推測されて、支払いの時に上流のシステムは戻りの結果がタイムアウトすることを受け入れていないで、それから上流のシステムは引き続きポーリングを調整して、この時ポーリングはredisロックに戻っ私はずっと問題があることを疑っています(私が地元で走っている間にロックが削除されていません.理論的には削除すべきですが、何の問題がありますか?)この問題を再現した後、最初の時間に顧客RedisDesktopManagerを通じてロックが削除されたかどうかを確認し、この時に削除されたかどうかを見て、bossに聞いて、bossの意味は上流システムがこの時タイムアウトしたので、すぐにポーリング(支払いとポーリングは同じロックである)を調整して、この時に支払いがまだ処理されていないので、クライアントredisロックに戻るすべての問題は、私の前の疑問を説明することができます.
度娘はredisロックの実現について、多くの方法があって、最近redisのpdfを1編過ぎたため、一度研究したいと思って、度娘はスクリプトの方式を使ってredis分布式ロックを実現することを見て、ただ1回スキャンして、表現したいのはredis分布式ロックを実現するのは多くの実現方式があって、必ずしもこのような方式を使う必要はありません
标红的部分有人理解的请留言告知,ありがとうございます!