redis spring 事务控制(模拟秒杀)

spring与redis的配置


    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        
        <property name="maxTotal" value="500" />
        
        <property name="maxIdle" value="100" />
        
        <property name="numTestsPerEvictionRun" value="1024" />
        
        <property name="timeBetweenEvictionRunsMillis" value="30000" />
        
        <property name="minEvictableIdleTimeMillis" value="1800000" />
        
        <property name="softMinEvictableIdleTimeMillis" value="10000" />
        
        <property name="maxWaitMillis" value="1500" />
        
        <property name="testOnBorrow" value="true" />
        
        <property name="testWhileIdle" value="true" />
        
        <property name="blockWhenExhausted" value="false" />
    bean>

     <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
        p:host-name="127.0.0.1" p:port="6379"  p:pool-config-ref="jedisPoolConfig"/>
     <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">    
        <property name="connectionFactory"   ref="connectionFactory" />    
    bean>

    <bean id="redisClient" class="redis.clients.jedis.JedisCluster">
        <constructor-arg name="nodes">
            <set>
                 <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.56.6">constructor-arg>
                    <constructor-arg name="port" value="7001">constructor-arg>
                bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.56.6">constructor-arg>
                    <constructor-arg name="port" value="7002">constructor-arg>
                bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.56.6">constructor-arg>
                    <constructor-arg name="port" value="7003">constructor-arg>
                bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.56.6">constructor-arg>
                    <constructor-arg name="port" value="7004">constructor-arg>
                bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.56.6">constructor-arg>
                    <constructor-arg name="port" value="7005">constructor-arg>
                bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.56.6">constructor-arg>
                    <constructor-arg name="port" value="7000">constructor-arg>
                bean>
             set>
        constructor-arg>
        <constructor-arg name="poolConfig" ref="jedisPoolConfig">constructor-arg>
    bean>

Maven文件配置pom.xml


    <dependency>                            
        <groupId>org.springframework.datagroupId> 
        <artifactId>spring-data-redisartifactId>
        <version>1.7.2.RELEASEversion>
    dependency>
    
    
    <dependency>
    <groupId>redis.clientsgroupId>
    <artifactId>jedisartifactId>
    <version>2.8.1version>
dependency>

事务管理

@SuppressWarnings("rawtypes")
    @Autowired
    private RedisTemplate redisTemplate;

    private final String key1 = "solenum";

    private final String ListKey1 = "getSole";

    @Override
    public String getSeckill(String key, int num,String username) {

        //BoundValueOperations bo = redisTemplate.boundValueOps(key);
        //int num1 = Integer.parseInt((String) bo.get());
            final int num1 = num;
            final String bb = username;
            @SuppressWarnings("unchecked")
            List ob = (List) redisTemplate.execute(new RedisCallback() {

                @Override
                public Object doInRedis(RedisConnection connection) throws DataAccessException {
                    connection.watch(key1.getBytes());

                    int number = Integer.parseInt(new String(connection.get(key1.getBytes())));
                    //判断秒杀的数量是否足够
                    if(number>0 && number >= num1){

                        String aa = String.valueOf(number - num1);

                        connection.multi();

                        connection.set(key1.getBytes(), aa.getBytes());
                        connection.rPush(ListKey1.getBytes(), bb.getBytes());

                        return connection.exec();
                    }else{
                        return null;
                    }


                }
            });
            /*redisTemplate.multi();



            List ob = redisTemplate.exec();*/
            String result = "";

            if(ob!=null){
                result = "抢到票!";
            }else{
                result = "没抢到票!";
            }

            return result;

    }

    @Override
    public String getSeckill(String key) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void set(String key, String value) {
        // TODO Auto-generated method stub
        BoundValueOperations bo = redisTemplate.boundValueOps(key);
        bo.set(value);
    } 
  

使用redis的watch去监控数量,当watch到数据改变了,则放弃事务,当发现数据没有被改变的时候,则可以开始事务并执行。
connection.multi() 开启事务
connection.exec() 执行事务,当事务执行完是,返回list,当没有执行时,返回null,从而可以判断事务是否已经执行了。
可以使用Apache Jmeter监控,发送并发请求。
简单的教程地址:http://www.cnblogs.com/ceshisanren/p/5639895.html
http://www.cnblogs.com/TankXiao/p/4045439.html

你可能感兴趣的:(redis,redis)