Spring Framework 中启动 Redis 事务操做

背景:redis

项目中遇到有一系列对Redis的操做,并须要保持事务处理。spring

环境:数据库

Spring version 4.1.8.RELEASEspa

Redis Server 2.6.12 (64位)code

spring-data-redis version 1.6.1.RELEASEblog

jedis version 2.7.3索引

 

使用Spring的@Transactional对redis操做进行控制事务

Spring Redis的配置文件以下:ip

<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事务管理控制。
string

业务代码以下:

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。

相关文章
相关标签/搜索