redis springトランザクション制御(アナログ秒殺)

19004 ワード

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()トランザクション接続をオンにします.exec()はトランザクションを実行し、トランザクションが完了するとlistを返し、実行しない場合nullを返し、トランザクションが実行されたかどうかを判断します.Apache Jmeterモニタを使用して、同時要求を送信できます.簡単なチュートリアルアドレス:http://www.cnblogs.com/ceshisanren/p/5639895.html http://www.cnblogs.com/TankXiao/p/4045439.html