Spring Framework 中啟動 Redis 事務操作


背景:

項目中遇到有一系列對Redis的操作,並需要保持事務處理。

環境:

Spring version 4.1.8.RELEASE

Redis Server 2.6.12 (64位)

spring-data-redis version 1.6.1.RELEASE

jedis version 2.7.3

 

使用Spring的@Transactional對redis操作進行控制

Spring Redis的配置文件如下:

<description>Jedis配置</description>

    <!-- Redis 配置 -->
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxIdle" value="${redis.maxIdle}" />
        <property name="maxTotal" value="${redis.maxActive}" />
        <property name="maxWaitMillis" value="${redis.maxWait}" />
        <property name="testOnBorrow" value="${redis.testOnBorrow}" />
    </bean>

    <bean id="jedisConnectionFactory"
        class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
        p:hostName="${redis.host}" p:port="${redis.port}" p:usePool="true"
        p:timeout="${redis.timeout}" p:password="${redis.pass}" p:database="${redis.default.db}"
        p:poolConfig-ref="jedisPoolConfig" />

    <bean id="stringRedisSerializer"
        class="org.springframework.data.redis.serializer.StringRedisSerializer" />

    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
        p:connection-factory-ref="jedisConnectionFactory"
        p:defaultSerializer-ref="stringRedisSerializer"
        p:enableTransactionSupport="false" />

    <bean id="redisTemplateTransactional" class="org.springframework.data.redis.core.RedisTemplate"
        p:connection-factory-ref="jedisConnectionFactory"
        p:defaultSerializer-ref="stringRedisSerializer"
        p:enableTransactionSupport="true" />

其中的p:enableTransactionSupport 需要設置為true,才能開啟Redis事務管理控制。

業務代碼如下:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.RedisSystemException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Autowired
private RedisTemplate<String, String> redisTemplateTransactional; @Transactional public void transactionalForRedis() throws Exception {   redisTemplateTransactional.boundValueOps("name").set("TEST_XXX");
  redisTemplateTransactional.boundValueOps(
"age").set("11");
  // 異常代碼   
for (int i = 0; i < 5; i++) {     if (i == 3) {
      throw new RedisSystemException("dsd", new Exception("myself exception....."));     }   } }

1.使用Spring的事務控制即可:@Transactional

2.其中會拋出異常處理,必須拋出RedisSystemException這個異常才能回滾,如果是自己封裝的異常類,不能回滾。

 

下面是結合數據庫操作與Redis,在同一個事務中進行控制的代碼樣例:

@Transactional
public void test() throws Exception {

        //操作Redis
        redisTemplateTransactional.boundValueOps("name").set("TEST_YYYY");
        redisTemplateTransactional.boundValueOps("age").set("80");

        //操作數據庫: JPA保存操作
        SimpleDemoEntity simpleDemoEntity = new SimpleDemoEntity();
        simpleDemoEntity.setRemark("nima");
        simpleDemoEntity.setWeixinId("1000");
        simpleDemoDao.saveAndFlush(simpleDemoEntity);
}

當遇到數據庫異常情況,比如,主鍵沖突,唯一索引值等數據庫異常,Redis的操作也可以正常回滾。

原因:

使用@Transactional 事務控制后,Spring對數據庫層面進行了完美的事務控制,那么當數據庫層拋出的所有異常都可以被事務控制管理。

而Redis或者使用Jedis本身的異常,或者業務異常類並沒有被Spring的事務控制管理。
而Spring-redis,給了我們一個可以拋出業務異常的渠道,那就是RedisSystemException。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM