RedisTemplate:execute與executePipelined

1.官網註釋

execute
@Nullable
public <T> T execute(RedisCallback<T> action)
  • Description copied from interface: RedisOperations
    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.

Specified by:
execute in interface RedisOperations

  • Type Parameters:
    T - return type
  • Parameters:
    • callback object that specifies the Redis action. Must not be null.
  • Returns:
  1. result object returned by the action or null

從以上註釋可知,該方法執行給定的Action在一次redis連接中。執行完成之後可以返回多個結果(List)。但是需要注意的是,它本身不支持解決事務,如果需要多個操作爲一個事務,需要使用專門的TransactionSynchronizationManager。當然了,如果我們一系列操作都是查詢,不需要開啓事務,使用這個很好。

executePipelined
public List<Object> executePipelined(SessionCallback<?> session)
  • Description copied from interface: RedisOperations
    Executes the given Redis session on a pipelined connection. Allows transactions to be pipelined. Note that the callback cannot return a non-null value as it gets overwritten by the pipeline.

Specified by:
executePipelined in interface RedisOperations

  • Parameters:
    • Session callback
  • Returns:
  1. of objects returned by the pipeline

所以,兩者的區別就在註釋中一目瞭然了。executePipelined是可以允許我們執行事務的。executePipelined還有一個需要注意的點,就是雖然重寫了回調函數,但是回調函數還是有可能返回空值的。註釋裏說是在被管道覆蓋的時候,這是在說什麼呢?

2.executePipelined

public List<Object> executePipelined(final SessionCallback<?> session, final RedisSerializer<?> resultSerializer) {
        Assert.isTrue(initialized, "template not initialized; call afterPropertiesSet() before using it");
        Assert.notNull(session, "Callback object must not be null");

        RedisConnectionFactory factory = getConnectionFactory();
        // bind connection
        RedisConnectionUtils.bindConnection(factory, enableTransactionSupport);
        try {
            return execute(new RedisCallback<List<Object>>() {
                public List<Object> doInRedis(RedisConnection connection) throws DataAccessException {
                    connection.openPipeline();
                    boolean pipelinedClosed = false;
                    try {
                        Object result = executeSession(session);
                        if (result != null) {
                            throw new InvalidDataAccessApiUsageException(
                                    "Callback cannot return a non-null value as it gets overwritten by the pipeline");
                        }
                        List<Object> closePipeline = connection.closePipeline();
                        pipelinedClosed = true;
                        return deserializeMixedResults(closePipeline, resultSerializer, hashKeySerializer, hashValueSerializer);
                    } finally {
                        if (!pipelinedClosed) {
                            connection.closePipeline();
                        }
                    }
                }
            });
        } finally {
            RedisConnectionUtils.unbindConnection(factory);
        }
    }

這裏判斷了executeSession的返回結果是否非空,這個函數最終會調用下面這個函數:

    /**
     * Executes all the given operations inside the same session.
     * 
     * @param operations Redis operations
     * @return return value
     */
    <K, V> T execute(RedisOperations<K, V> operations) throws DataAccessException;

正如註釋中所說的那樣,這個函數會執行當前會話中的所有的operation,以判斷是否已經有了操作,保證該事務不被其它操作干擾。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章