Lesson 3
Handling Transactions with Pipelines in Redis
Handling Transactions with Pipelines

Welcome back! We're moving on to the next essential part of our Redis-based backend system project — handling transactions with pipelines. This will help us execute multiple Redis commands as a single atomic operation. Remember, you've already gotten comfortable with managing user data and leaderboards. This unit will take it a step further by optimizing these operations using pipelines.

What You'll Build

Before we dive in, let's recap what you’ll be focusing on in this unit. The key tasks include:

  1. Adding user data with expiration using pipelines: We will group multiple commands into one pipeline to add user data more efficiently.
  2. Adding scores to a leaderboard using pipelines: Using pipelines to add scores will ensure these operations are atomically executed.
  3. Executing the pipeline: We'll ensure the grouped commands in the pipeline are executed together.

These tasks will help us understand how pipelines can enhance performance and consistency in our Redis operations.

Adding User Data Using Pipelines

To add user data with expiration, we use the addUserWithPipeline method from the User class. This method takes a Pipeline object and ensures that user data is stored with an expiration of one day:

Java
1// Add user data to Redis using a pipeline 2public static void addUserWithPipeline(Pipeline pipeline, User user) { 3 String userKey = "user:" + user.getUsername(); 4 String jsonData = gson.toJson(user.getData()); 5 pipeline.setex(userKey, (int) Duration.ofDays(1).getSeconds(), jsonData); 6}

In the Main class, this method is called for multiple users. The pipeline ensures that all commands are grouped into a single batch:

Java
1try (Pipeline pipeline = jedis.pipelined()) { 2 for (User user : new User[]{user1, user2, user3}) { 3 User.addUserWithPipeline(pipeline, user); 4 } 5 pipeline.sync(); // Sends all buffered commands to the Redis server and waits for their execution results. 6}

This ensures that the commands are sent and executed together, reducing the number of network round-trips.

Adding Scores to a Leaderboard Using Pipelines

To add scores to a leaderboard, the addScoreWithPipeline method is used. It adds user scores to the leaderboard sorted set:

Java
1// Add user score to the leaderboard using a pipeline 2public static void addScoreWithPipeline(Pipeline pipeline, User user) { 3 pipeline.zadd("leaderboard", user.getScore(), user.getUsername()); 4}

In the Main class, this is also part of the pipeline block:

Java
1try (Pipeline pipeline = jedis.pipelined()) { 2 for (User user : new User[]{user1, user2, user3}) { 3 User.addScoreWithPipeline(pipeline, user); 4 } 5 pipeline.sync(); 6}

Both user data and scores are added in one pipeline block to ensure efficiency and atomic execution.

Executing the Pipeline

Once all the commands are added to the pipeline, calling pipeline.sync() sends the batch of commands to Redis for execution:

Java
1pipeline.sync();

This method ensures that all commands in the pipeline are executed as a single atomic operation. The sync() method is blocking; it waits for Redis to execute all commands in the pipeline and returns their results once the execution is complete.

Why It Matters

Using pipelines is critical for building scalable and efficient backend systems. They allow you to:

  • Optimize Performance: Reduce the number of network round-trips between your application and Redis.
  • Maintain Consistency: Ensure atomic execution of multiple related operations.
  • Simplify Code: Group commands logically, making your code easier to maintain.

Let's go! The more you practice, the better you'll get at building efficient backend systems.

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.