Redis
 sql >> Datenbank >  >> NoSQL >> Redis

Spring RedisConnectionFactory mit Transaktion, die keine Verbindung zu Pool zurückgibt und dann blockiert, wenn sie erschöpft ist

Ich denke, das Problem ist, dass exec() aufgerufen wird teilt der Vorlage nicht mit, dass Sie mit der Verbindung tatsächlich fertig sind, sodass sie nicht an den Pool zurückgegeben werden kann.

Laut der Dokumentation sollen Sie Ihren Code in einen SessionCallback packen und führen Sie es mit RedisTemplate.execute(SessionCallback<T> callback) aus die die Verbindung zum Pool zurückgibt, nachdem Ihr Rückruf ausgeführt wurde.

So:

template.execute(new SessionCallback<List<Object>>() {
    public List<Object> execute(RedisOperations operations) throws DataAccessException {
        operations.multi();
        aMap.put(A_KEY, a.toString(), a);
        bMap.put(B_KEY, b.toString(), b);
        cMap.put(C_KEY, c.toString(), c);
        return operations.exec();
    }
});

Spring Data Redis unterstützt auch @Transactional was die Verbindung automatisch für Sie bindet/entbindet, aber erfordert, dass Sie die Methode in einer Bean implementieren, die abgefangen werden kann (d. h. sie kann nicht final sein ) und Transaktionen werden nur gestartet, wenn sie von außerhalb der Bean ausgeführt werden (d. h. nicht von einer anderen Methode in derselben Klasse oder einer untergeordneten/übergeordneten Klasse).

Sie aktivieren die Transaktionsunterstützung bereits in der Vorlage mit redisTemplate.setEnableTransactionSupport(true); Sie sollten also startklar sein:

@Transactional
public void put(A a, B b, C c) {
    aMap.put(A_KEY, a.toString(), a);
    bMap.put(B_KEY, b.toString(), b);
    cMap.put(C_KEY, c.toString(), c);
}