Redis provides support for transactions through the multi, exec, and discard commands. These operations are available on RedisTemplate. However, RedisTemplate is not guaranteed to execute all operations in the transaction with the same connection.
Spring Data Redis provides the SessionCallback interface for use when multiple operations need to be performed with the same connection, such as when using Redis transactions. The following example uses the multi method:
public T execute(SessionCallback 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);
}
}
四、SessionCallback方式的示例代码:
1 RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration("192.168.19.90");
2 JedisConnectionFactory factory = new JedisConnectionFactory(configuration);
3 factory.afterPropertiesSet();
4 5 RedisTemplate template = new RedisTemplate<>();
6 template.setConnectionFactory(factory);
7 template.setDefaultSerializer(new GenericFastJsonRedisSerializer());
8 StringRedisSerializer serializer = new StringRedisSerializer();
9 template.setKeySerializer(serializer);
10 template.setHashKeySerializer(serializer);
1112 template.afterPropertiesSet();
1415try {
16 List txResults = template.execute(new SessionCallback>() {
17 @Override
18public List execute(RedisOperations operations) throws DataAccessException {
1920 operations.multi();
2122 operations.opsForValue().set("test_long", 1);
23int i = 1/0;
24 operations.opsForValue().increment("test_long", 1);
2526// This will contain the results of all ops in the transaction27return operations.exec();
28 }
29 });
3031 } catch (Exception e) {
32 System.out.println("error");
33 e.printStackTrace();
34 }
List txResults = template.execute(new SessionCallback>() {
@Override
public List execute(RedisOperations operations) throws DataAccessException {
operations.multi();
operations.opsForValue().set("test_long", 1);
int i = 1/0;
operations.opsForValue().increment("test_long", 1);
// This will contain the results of all ops in the transaction
return operations.exec();
}
});
执行上述代码,执行到int i = 1/0时,会抛出异常。我们需要检查,抛出异常后,是否发送了“discard”命令给redis 服务器?