Redis Lua Script With Spring Boot

Overview:

In this tutorial, I would like to show you Redis Lua Script with Spring Boot to execute a set of operations as a single transaction or to have some kind of constraints when you do Redis transactions.

Redis Lua Script:

When a client wants to execute a set of operations on Redis Database, instead of sending all the commands one by one on a network, we could create our own extensions (kind of) on Redis Database using Lua Script and execute the operations as a single transaction.

The Redis Lua Script gets compiled for the first time and then using the SHA, the loaded script can be invoked any time.

Sample Application:

We are going to consider a simple Bank application in which Redis is the primary DB. We have set of accounts. The users can transfer money from 1 account to another.

Lets see how to implement the money transfer by using Redis Lua Script with Spring Boot.

Project Setup:

Create a Spring Boot project with below dependencies.

We are going to assume that Redis maintains all the accounts in an account hash as shown below. a and b are account names and the values are the corresponding account balances.

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

Redis Lua Script – Money Transfer:

The following lua script is responsible for the money transfer business functionality.

  • The script will be invoked with 2 keys and 1 arg.
  • key 1 represents the from account and key 2 represents to account.
  • The arg is the amount to be transferred.
  • If the from account has enough balance, then we will deduct money from 1 account and transfer to another account.
--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
  • the above script is located under src/main/resources/scripts.

Redis Lua Script – Money Transfer Service:

  • First create a RedisScript bean show here.
@Configuration
public class ScriptConfig {

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

}
  • Create a service class which accepts fromAccout, toAccount and the amount to be transferred. We would invoke the RedisScript by passing the parameters.
@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));
    }

}

Demo:

Once everything is ready, We can test as shown here.

@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")
        );
    }
}

Output:

80
40

Summary:

we were able to successfully demonstrate a business functionality as a single transaction by using Redis Lua Script with Spring Boot.

Learn more about Redis with Spring Boot.

The source code is available here.

Happy learning 🙂

Share This:

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.