事業
Redisトランザクションの本質:
コマンドのコレクション。トランザクション内のすべてのコマンドはシリアル化され、トランザクションの実行中に順番に実行されます。
Redisトランザクションの特徴:
- 一度
- 順次
- 独占権
Redisトランザクションには分離レベルの概念がありません
すべてのコマンドがトランザクションで直接実行されるわけではありません。Execは、実行コマンドが開始されたときにのみ実行されます
Redisの単一コマンドは原子性が保証されていますが、トランザクションは原子性が保証されていません!
Redisの業務
- トランザクションを開始(マルチ)
- チームに参加するための命令(....)
- 実行トランザクション(exec)
127.0.0.1:6379> multi #开启事务
OK
#命令入队
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> get k3
QUEUED
127.0.0.1:6379> exec #执行事务
1) OK
2) OK
3) OK
4) "v3"
あきらめる
127.0.0.1:6379> multi #开启事务
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k4 v4
QUEUED
127.0.0.1:6379> discard #取消事务
OK
127.0.0.1:6379> get k4 #事务队列中的命令都不会被执行
(nil)
2つの異常
1.コンパイル例外(コマンドが間違っています)、トランザクション内のすべてのコマンドは実行されません
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> getset k3 #错误命令
(error) ERR wrong number of arguments for 'getset' command
127.0.0.1:6379> set k4 v4
QUEUED
127.0.0.1:6379> exec #执行是事务报错
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get k4 #所有的命令都不会执行
(nil)
2.ランタイム例外(1/0)。トランザクションキューに文法がある場合、コマンドを実行すると、他のコマンドが正常に実行され、間違ったコマンドが例外をスローします。
127.0.0.1:6379> set k1 "v1"
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr k1 #字符串自增1 会执行失败
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> exec
1) (error) ERR value is not an integer or out of range #虽然第一条命令报错了,但是还是正常执行成功了
2) OK
3) OK
127.0.0.1:6379> get k2
"v2"
モニターウォッチ(インタビューFAQ)
悲観的ロック:
何がロックされるかに関係なく、いつでも問題が発生すると考えて非常に悲観的
楽観的ロック:
非常に楽観的で、いつでも問題はないのでロックされることはないと思いますので、データを更新する際は、この期間に誰かがこのデータを変更したかどうかを判断してください。
時計の使用
- バージョンを取得
- 更新時にバージョンを比較する
- Redisテスト監視テスト
通常の実行は成功しました:
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch money #监视money对象
OK
127.0.0.1:6379> multi #事务正常结束,数据期间没有发生改变,这个时候正常执行成功!
OK
127.0.0.1:6379> decrby money 20
QUEUED
127.0.0.1:6379> incrby out 20
QUEUED
127.0.0.1:6379> exec
1) (integer) 80
2) (integer) 20
マルチスレッドの変更値をテストし、watchをredisの楽観的ロック操作として使用します
127.0.0.1:6379> watch money #监视money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby moeney 10
QUEUED
127.0.0.1:6379> incrby out 10
QUEUED
127.0.0.1:6379> exec #执行之前,另外一个线程修改了money的值,就会导致事务执行失败!
(nil)
変更に失敗しました:
- トランザクションの実行が失敗したことが判明した場合、最初にロックが解除されます
- 最新の値を取得して再度監視する
- 監視値が変化していないか確認し、変化がない場合は実行可能、変更に失敗した場合は実行を継続し、アンロックと監視を継続します。
127.0.0.1:6379> unwatch #如果发现事务执行失败,就先解锁
OK
127.0.0.1:6379> watch money #获取最新的值,再次监视
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby money 60
QUEUED
127.0.0.1:6379> incrby out 60
QUEUED
127.0.0.1:6379> exec #比对监视的值是否发生变化,如果没有发生变化,可以执行,如果变化就执行失败,继续解锁再次监视。
1) (integer) 1020
2) (integer) 80