1.読み取り/書き込みロックとは何ですか
読み取り/書き込みロックに関しては、その名前が示すように、読み取りと書き込みのシナリオで使用される2種類のロックです。
読み取りロックは共有ロックであり、書き込みロックは排他ロックです。これはどういう意味ですか?
つまり、書き込みロックは独立してのみ存在でき、読み取りロックは一緒に存在できます
一般に、同じ名前の読み取り/書き込みロックでは、書き込みロックが表示された場合、同じ名前の読み取りロックや同じ名前の書き込みロックをロックすることはできません。
読み取りロックがある場合、同じ名前の読み取りロックはロックできますが、同じ名前の書き込みロックはロックできません。
2.下の場合
実際、これはすべてデータの整合性に準拠するように設計されています。考えてみてください。
テーブルにデータを書き込むと、別の人がこのテーブルにデータを読み取っています
あなたがデータを書き終えた後、彼は最新のデータを読む必要がありますか?現時点では、読み取り/書き込みロックを使用して制限することができます
もちろん、一部のビジネスでデータの整合性に対する高い要件がない場合は、読み取り/書き込みロックを追加する必要はありません。
もちろん、あなたはすべて読んでいるので、この時点で読み取りロックを追加する必要があります。あなたがあなたを読んで、私が私のものを読んだ場合、それはあなたに影響を与えません。
しかし、あなたが読んでいる間に、他の人が書き込みロックを取得して書き込みの準備をします。それは成功しますか?
読み取りが最初に行われ、書き込みがここで行われるため、明らかに機能しませんが、キャッシュまたはデータベースに書き込む前に、そこで読み取りを終了する保証はありません。
最初に書き込む場合、他のパーティが書き込みの前後にデータベース内のデータを読み取る可能性があるため、一貫性を保つために、書き込みロックを排他ロックとして設計するのが妥当です。
3.例を見てください
例を挙げてください、ここに1つのシーンだけがあります
つまり、ここで書き込みロックが解除される前に、書き込みロックが解除されるまで反対側の読み取りロックがブロックされ、読み取りロックを正常に追加して読み取りを開始できます。
@Autowired
RedissonClient redissonClient;
@Autowired
StringRedisTemplate stringRedisTemplate;
@RequestMapping({"/write"})
@ResponseBody
public void write(){
//获取一把读写锁,只要名称一样就是同一把锁
RReadWriteLock rwLock = redissonClient.getReadWriteLock("rw-lock");
RLock rLock = rwLock.writeLock();
rLock.lock();
try {
Thread.sleep(30000);
String uuid = UUID.randomUUID().toString();
stringRedisTemplate.opsForValue().set("test-key",uuid);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
//释放锁
rLock.unlock();
}
}
@RequestMapping({"/read"})
@ResponseBody
public String read(){
//获取一把读写锁,只要名称一样就是同一把锁
RReadWriteLock rwLock = redissonClient.getReadWriteLock("rw-lock");
RLock rLock = rwLock.readLock();
rLock.lock();
String uuid = null;
try {
uuid = stringRedisTemplate.opsForValue().get("test-key");
} catch (Exception e) {
e.printStackTrace();
}finally {
//释放锁
rLock.unlock();
return uuid;
}
}
上に書いたウィンドウが回転し続け、下の読み取りウィンドウも同じであるという現象です。上の円が書き込みを終えると、書き込みロックが解除され、下の画面が表示されます。