首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

SSH 框架整合 Redis 實戰(二):增刪改查同步雙寫實現

     編輯:Java 綜合教學

SSH 框架整合 Redis 實戰(二):增刪改查同步雙寫實現

承接上篇環境搭建,本文展示如何在 Struts2 + Spring + Hibernate (SSH) 架構中,通過 RedisTemplate 實現課程(Clas)實體的 Redis 緩存增刪改查,並同步雙寫 MySQL,保證數據一致性。

核心組件

  • RedisService 接口:封裝 String、Hash、List 操作。
  • RedisTool.getRedisService():單例獲取服務實例。
  • ClasService:Hibernate 業務層,負責 MySQL 持久化。

新增:RClasAction

public class RClasAction extends ActionSupport {
    @Autowired private ClasService clasService;
    private RedisService rs = RedisTool.getRedisService();
    private Clas clas;

    public String execute() {
        saveClas(clas);
        return SUCCESS;
    }

    private void saveClas(Clas c) {
        // 1. 從 Redis 列表獲取最大 ID
        List ids = rs.getList("clas:id");
        int newId = Integer.parseInt(ids.get(ids.size() - 1)) + 1;

        // 2. 更新 ID 列表與計數器
        rs.rightPushList("clas:id", String.valueOf(newId));
        int count = Integer.parseInt(rs.get("clas:count"));
        rs.set("clas:count", String.valueOf(count + 1), -1);

        // 3. 寫入 Hash 結構:clas:{id} → {ID, NAME, COMMENT}
        Map map = new HashMap<>();
        map.put("ID", String.valueOf(newId));
        map.put("NAME", c.getName());
        map.put("COMMENT", c.getComment());
        rs.addHash("clas:" + newId, map);

        // 4. 同步 MySQL
        clasService.saveClas(c);
    }
}

刪除:RClasDeleteAction

public class RClasDeleteAction extends ActionSupport {
    @Autowired private ClasService clasService;
    private RedisService rs = RedisTool.getRedisService();
    private int id;

    public String execute() {
        deleteClas(id);
        clasService.deleteClas(id); // 同步 MySQL
        return SUCCESS;
    }

    private void deleteClas(int id) {
        rs.del("clas:" + id);                    // 刪除 Hash
        int count = Integer.parseInt(rs.get("clas:count"));
        rs.set("clas:count", String.valueOf(count - 1), -1); // 計數器 -1
        rs.delListItem("clas:id", String.valueOf(id));        // 從 ID 列表移除
    }
}

修改:RClasUpdateAction

public class RClasUpdateAction extends ActionSupport {
    @Autowired private ClasService clasService;
    private RedisService rs = RedisTool.getRedisService();
    private Clas clas;

    public String execute() {
        Map map = new HashMap<>();
        map.put("ID", String.valueOf(clas.getId()));
        map.put("NAME", clas.getName());
        map.put("COMMENT", clas.getComment());
        rs.putHash("clas:" + clas.getId(), map); // 覆蓋更新 Hash
        clasService.updateClas(clas);            // 同步 MySQL
        return SUCCESS;
    }
}

RedisService 關鍵實現

// Hash 新增
public synchronized void addHash(K key, Map map) {
    redisTemplate.opsForHash().putAll(key, map);
}

// Hash 更新
public synchronized void putHash(K key, Map map) {
    redisTemplate.boundHashOps(key).putAll(map);
}

// List 刪除指定元素(相當於 LREM key 1 value)
public synchronized void delListItem(K key, V value) {
    redisTemplate.opsForList().remove(key, 1, value);
}

一致性與擴展建議

  • 雙寫順序:建議先寫 MySQL(事務保障),再寫 Redis;或引入 Canal 監聽 Binlog 異步更新緩存,避免雙寫不一致。
  • 事務邊界:Action 方法應加 @Transactional,確保 MySQL 操作原子性。
  • 緩存穿透/雪崩:ID 列表、計數器設定永不過期;業務數據設定 TTL + 隨機值。
  • 分佈式鎖:高併發 ID 生成可用 Redis Lua 腳本或 Snowflake 算法替代列表自增。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved