Redis RedisTemplate 的 execute()方法

Redis 批量操作

如果频繁地使用Redis,比如在 for循环中调用 redis,有时可能会报错: Could not get a resource from the pool。

这是因为 Redis的连接数是有限的,打开了Redis的连接,用完记得要关闭,如果连接数不够了就会报错。

Redis 批量操作,可以使用 RedisTemplate 的 execute()方法。

RedisTemplate 源码

  • org.springframework.data.redis.core.RedisOperations

  • org.springframework.data.redis.core.RedisTemplate

RedisTemplate 的 execute()方法

org.springframework.data.redis.core.RedisTemplate#execute(org.springframework.data.redis.core.SessionCallback)

execute() 方法,可以在一次连接中进行多个命令操作。执行完会自动关闭连接。

	/**
	 * Executes a Redis session. Allows multiple operations to be executed in the same session enabling 'transactional'
	 * capabilities through {@link #multi()} and {@link #watch(Collection)} operations.
	 *
	 * @param <T> return type
	 * @param session session callback. Must not be {@literal null}.
	 * @return result object returned by the action or <tt>null</tt>
	 */
	@Override
	public <T> T execute(SessionCallback<T> session) {

		Assert.isTrue(initialized, "template not initialized; call afterPropertiesSet() before using it");
		Assert.notNull(session, "Callback object must not be null");

		RedisConnectionFactory factory = getRequiredConnectionFactory();
		// 打开连接
		RedisConnectionUtils.bindConnection(factory, enableTransactionSupport);
		try {
			return session.execute(this);
		} finally {
			//执行完会自动关闭连接
			RedisConnectionUtils.unbindConnection(factory);
		}
	}

execute()的SessionCallback参数和RedisCallback参数

SessionCallback 比 RedisCallck 更好些,优先使用 SessionCallback 。

使用SessionCallback , 还可以配合multi() 和 watch() 进行事务操作。

/**
 * Executes the given action within a Redis connection. Application exceptions thrown by the action object get
 * propagated to the caller (can only be unchecked) whenever possible. Redis exceptions are transformed into
 * appropriate DAO ones. Allows for returning a result object, that is a domain object or a collection of domain
 * objects. Performs automatic serialization/deserialization for the given objects to and from binary data suitable
 * for the Redis storage. Note: Callback code is not supposed to handle transactions itself! Use an appropriate
 * transaction manager. Generally, callback code must not touch any Connection lifecycle methods, like close, to let
 * the template do its work.
 *
 * @param <T> return type
 * @param action callback object that specifies the Redis action. Must not be {@literal null}.
 * @return a result object returned by the action or <tt>null</tt>
 */
@Nullable
<T> T execute(RedisCallback<T> action);

/**
 * Executes a Redis session. Allows multiple operations to be executed in the same session enabling 'transactional'
 * capabilities through {@link #multi()} and {@link #watch(Collection)} operations.
 *
 * @param <T> return type
 * @param session session callback. Must not be {@literal null}.
 * @return result object returned by the action or <tt>null</tt>
 */
@Nullable
<T> T execute(SessionCallback<T> session);

execute() 使用示例:

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    
    
    public void testExecute() {
        String userId = "userId";
        stringRedisTemplate.opsForValue().set(userId+"123", "lin");
        stringRedisTemplate.opsForValue().set(userId+"456", "wu");
        stringRedisTemplate.opsForValue().set(userId+"789", "chen");

        Map<String, String> map = new HashMap<>();
        stringRedisTemplate.execute(new SessionCallback<String>() {
            @Override
            public <K, V> String execute(@NonNull RedisOperations<K, V> redisOperations) throws DataAccessException {
                List<String> list = Arrays.asList("123", "456", "789");
                for (String id : list) {
                    String key = userId + id;
                    String value = (String) redisOperations.opsForValue().get(key);
                    map.put(key, value);
                }
                return null;
            }
        });

        map.forEach((k, v) -> System.out.println(k + ",val:" + v));
    }

posted on 2023-02-02 11:20  乐之者v  阅读(1510)  评论(0编辑  收藏  举报

导航