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。

  • 相关阅读:
    超文本传输协议 HTTP/1.0 Hyptertext Transfer Protocol
    VB.NET中使用代表对方法异步调用
    蚂蚁解道德经(1)[转载]
    vb.net 类的属性的设置和获取问题
    VB.net入门(6):类~构造函数,事件
    什么是Ajax技术
    千里之外
    一个asp.net2005的页面文件调用CSS样式的BUG
    一个.net发送HTTP数据实体的类
    利用ASP发送和接收XML数据的处理方法
  • 原文地址:https://www.cnblogs.com/yangwn/p/5260670.html
Copyright © 2011-2022 走看看