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

来源:互联网 发布:车辆检测软件 编辑:程序博客网 时间:2024/06/05 16:08

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" />        <!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 -->        <property name="maxWaitMillis" value="1500" />        <!-- 在获取连接的时候检查有效性, 默认false -->        <property name="testOnBorrow" value="true" />        <!-- 在空闲时检查有效性, 默认false -->        <property name="testWhileIdle" value="true" />        <!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认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>
<!-- redis集群配置 -->    <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

<!--1.7.2 开始支持Redis 集群-->    <dependency>                                    <groupId>org.springframework.data</groupId>         <artifactId>spring-data-redis</artifactId>        <version>1.7.2.RELEASE</version>    </dependency>    <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->    <!-- <dependency>        <groupId>redis.clients</groupId>        <artifactId>jedis</artifactId>        <version>2.9.0</version>    </dependency> -->    <dependency>    <groupId>redis.clients</groupId>    <artifactId>jedis</artifactId>    <version>2.8.1</version></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<String, Object> bo = redisTemplate.boundValueOps(key);        //int num1 = Integer.parseInt((String) bo.get());            final int num1 = num;            final String bb = username;            @SuppressWarnings("unchecked")            List<Object> ob = (List<Object>) redisTemplate.execute(new RedisCallback<Object>() {                @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<String,Object> 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

原创粉丝点击