zoukankan      html  css  js  c++  java
  • 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。

  • 相关阅读:
    171. Excel Sheet Column Number (Easy)
    349. Intersection of Two Arrays (Easy)
    453. Minimum Moves to Equal Array Elements (Easy)
    657. Judge Route Circle (Easy)
    CSS笔记
    保存页面状态
    UI开发总结
    ubuntu 下配置munin
    反向代理配置
    JavaScript 高级程序设计第二版
  • 原文地址:https://www.cnblogs.com/yangwn/p/5260670.html
Copyright © 2011-2022 走看看