Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use RedisTemplat to implement simple distributed Lock

2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly explains "how to use RedisTemplat to achieve simple distributed locks". The content of the explanation is simple and clear, and it is easy to learn and understand. Please follow the editor's ideas to study and learn "how to use RedisTemplat to achieve simple distributed locks".

Implement Redis distributed lock preparation without using the redisson framework:

Import dependency

Org.springframework.boot spring-boot-starter-data-redis

Write RedisConfig classes

@ Configurationpublic class RedisConfig {@ Bean public RedisTemplate redisTemplate (RedisConnectionFactory redisConnectionFactory) {RedisTemplate redisTemplate = new RedisTemplate (); / String type key serializer redisTemplate.setKeySerializer (new StringRedisSerializer ()); / / String type value serializer redisTemplate.setValueSerializer (new GenericJackson2JsonRedisSerializer ()); / / Hash type key serializer redisTemplate.setHashKeySerializer (new StringRedisSerializer ()) / / value serializer of Hash type redisTemplate.setHashValueSerializer (new GenericJackson2JsonRedisSerializer ()); / / inject connection factory into redisTemplate.setConnectionFactory (redisConnectionFactory); return redisTemplate;}}

1. Write test module 1.1 in SpringBootTest: use placeholders to lock:

Placeholder locking problem: the lock cannot be released when an exception occurs, causing subsequent threads to become deadlocked

@ SpringBootTestclass ApplicationTests {@ Autowired private RedisTemplate redisTemplate;@Testpublic void lodsTest01 () {ValueOperations valueOperations = redisTemplate.opsForValue (); / / create a placeholder. If key does not exist, Boolean isLock = valueOperations.setIfAbsent ("K1", "v1") can be set successfully. / / if the occupation is successful, perform normal operation if (isLock) {/ / set a name to redis valueOperations.set ("name", "xxxx"); / / take out name String name = (String) valueOperations.get ("name") from redis; System.out.println ("name =" + name) / / manually create exception Integer.parseInt ("xxxx"); / / delete lock redisTemplate.delete ("K1") at the end of operation;} else {System.out.println ("thread is in use, please try later");}

test

The first thread failed to release the lock with an exception:

After that, all threads are inaccessible:

Solution: add a valid time to the lock.

1.2: use placeholders to set valid time to resolve deadlock issues:

Placeholder setting validity time problem: even if an exception occurs in a thread, the placeholder expires and the lock is released. However, when a large number of threads visit at the same time, if thread 1 is affected by external factors (network fluctuations, server problems, etc.), the business of thread 1 has not been completed, but the effective time for the lock is up, the next thread will come in. There will be thread unsafe situations, and threads will delete locks from each other.

@ Test public void testLock02 () {ValueOperations valueOperations = redisTemplate.opsForValue (); / / if key does not exist, set a valid time to prevent thread exception from deadlock Boolean isLock = valueOperations.setIfAbsent ("K1", "v1", 5, TimeUnit.SECONDS) / / if the occupation is successful, perform normal operation if (isLock) {/ / set a name to redis valueOperations.set ("name", "xxxx"); / / take out name String str = (String) valueOperations.get ("name") from redis; System.out.println ("name =" + str) / / create exception Integer.parseInt ("xxxx"); / / delete lock redisTemplate.delete ("K1") at the end of operation;} else {System.out.println ("thread in use, please try again later");}}

Solution: use the lua script to set a random number for the value corresponding to the key of each lock

1.3Use lua scripts to resolve thread unsafety issues:

Lua scripts can be written on the Redis server:

Pros: running fast on the server

Disadvantages: it is troublesome to modify the code

Lua scripts can be sent through java

Advantages: easy to modify the code

Cons: it takes up network resources every time a request is sent

1.3.1: write lua scripts

If redis.call ("get", KEYS [1]) = ARGV [1] then return redis.call ("del", KEYS [1]) else return 0end

1.3.2: modify the ReidsConfig class

@ Bean public DefaultRedisScript defaultRedisScript () {DefaultRedisScript redisScript = new DefaultRedisScript (); / / lock.lua script location and application.yml sibling directory redisScript.setLocation (new ClassPathResource ("lock.lua")); / / set type to boolean redisScript.setResultType (Boolean.class); return redisScript;}

1.3.3: write test modules

@ Test public void testLock03 () {ValueOperations valueOperations = redisTemplate.opsForValue (); String value = UUID.randomUUID (). ToString (); / / it can only be set successfully if key does not exist. Set a value with value as a random number to prevent thread unsafe Boolean isLock = valueOperations.setIfAbsent ("K1", value, 5, TimeUnit.SECONDS) due to too many threads. / / if the occupation is successful, perform normal operation if (isLock) {/ / set a name to redis valueOperations.set ("name", "xxxx"); / / take out name String name = (String) valueOperations.get ("name") from redis; System.out.println ("name =" + name) / / send a lua script for redis to delete the lock corresponding to value Boolean aBoolean = (Boolean) redisTemplate.execute (redisScript, Collections.singletonList ("K1"), value); System.out.println (aBoolean);} else {System.out.println ("thread in use, please try later");}}

Test results:

Successfully save the name value to redis, delete the lock and return to true

The lock will be deleted normally, leaving only name:

Thank you for reading, the above is the content of "how to use RedisTemplat to achieve simple distributed locks". After the study of this article, I believe you have a deeper understanding of how to use RedisTemplat to achieve simple distributed locks, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report