Skip to content

Dashboard

[Redis] - Spring Boot With Redis Lua Script

Created by Admin

Trong bài viết này chúng ta sẽ cùng tìm hiểu Redis Lua Script với Spring Boot để thực hiện một tập hợp các hành động như một transaction hoặc thực hiện một số loại ràng buộc khi chúng ta thực hiện các Redis transaction.

Một số bài viết cùng chủ đề, mọi người có thể tham khảo tại đây:

Redis Lua Script

Khi chúng ta muốn thực hiện một tập hợp các hành động trên Cơ sở dữ liệu Redis, thay vì gửi lần lượt các lệnh, chúng ta có thể tạo các phần mở rộng của riêng mình trên Cơ sở dữ liệu Redis bằng cách sử dụng Lua Script và thực hiện các hành động như một transaction. Redis Lua Script được biên dịch lần đầu tiên và sau đó có thể được gọi bất kỳ khi nào.

Sample Application

Ví dụ chúng ta sẽ chuyển tiền giữa 2 tài khoản của người dùng.

Giả sử chúng ta có thông tin 2 tài khoản ab với số dư lần lượt là 100$20$ như sau:

{
  "a": "100",
  "b": "20"
}

Lua Script

Tập lệnh Lua Script dưới đây chịu trách nhiệm về chức năng chuyển tiền. Tập lệnh sẽ được gọi với 2 khóa (KEY) và 1 đối số (ARG). KEY1 đại diện cho tài khoản người chuyển và KEY2 đại diện cho tài khoản người nhận. Đối số là số tiền được chuyển. Nếu tài khoản người chuyển có đủ số dư thì chúng ta sẽ trừ tiền trong tài khoản người chuyển và chuyển sang tài khoản người nhận.

--moneyTransfer.lua
local account = 'account'
local fromBalance = tonumber(redis.call('HGET', account, KEYS[1]))
local toBalance = tonumber(redis.call('HGET', account, KEYS[2]))
local amount = tonumber(ARGV[1])
if fromBalance >= amount
then
    redis.call('HSET', account, KEYS[1], fromBalance - amount)
    redis.call('HSET', account, KEYS[2], toBalance + amount)
    return true
end
return false

Tập lệnh trên nằm trong src /main/resources/scripts

Redis Lua Script – Money Transfer Service

Bây giờ đến bước sử dụng file Lua Script chúng ta đã định nghĩa tập lệnh bên trên.

Đầu tiên là tạo RedisScript Bean

@Configuration
public class ScriptConfig {

    @Bean
    public RedisScript<Boolean> script() {
        Resource scriptSource = new ClassPathResource("scripts/moneyTransfer.lua");
        return RedisScript.of(scriptSource, Boolean.class);
    }

}

Tạo một class MoneyTransferService nhận các tham số fromAccout, toAccountamount để thực hiện nghiệp vụ chuyển tiền. Chúng ta sẽ gọi RedisScript bằng cách truyền các tham số:

@Service
public class MoneyTransferService {

    @Autowired
    private RedisScript<Boolean> script;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public void transfer(String fromAccount, String toAccount, int amount){
        this.redisTemplate
                .execute(script, List.of(fromAccount, toAccount), String.valueOf(amount));
    }

}

Tạo file Main để chạy sample application:

@SpringBootApplication
public class RedisLuaScriptApplication implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(RedisLuaScriptApplication.class, args);
    }

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private MoneyTransferService service;

    @Override
    public void run(String... args) throws Exception {

        // initialize few accounts
        this.redisTemplate.opsForHash().put("account", "a", "100");
        this.redisTemplate.opsForHash().put("account", "b",  "20");

        // transfer money with lua script
        this.service.transfer("a", "b", 20);

        // check the results
        System.out.println(
                this.redisTemplate.opsForHash().get("account", "a")
        );
        System.out.println(
                this.redisTemplate.opsForHash().get("account", "b")
        );
    }
}

Kết quả:

80
40

Tổng kết

Vậy là chúng ta vừa cấu hình chạy một ứng dụng Spring Boot với Lua Script. Hi vọng bài viết hữu ích với mọi người.

Nguồn: https://thenewstack.wordpress.com/2021/11/24/redis-spring-boot-with-redis-lua-script/

Follow me: thenewstack.wordpress.com

Source: https://viblo.asia/p/redis-spring-boot-with-redis-lua-script-maGK7ByD5j2