如需最新的稳定版本,请使用 Spring Data Redis 3.4.0! |
Redis 事务
Redis 通过 、 和 命令为事务提供支持。
这些操作在 RedisTemplate
上可用。
但是,不能保证使用同一连接运行事务中的所有操作。multi
exec
discard
RedisTemplate
Spring Data Redis提供了 SessionCallback
接口,以便在需要使用相同的操作执行多个操作时使用,例如在使用 Redis 事务时。以下示例使用该方法:connection
multi
//execute a transaction
List<Object> txResults = redisOperations.execute(new SessionCallback<List<Object>>() {
public List<Object> execute(RedisOperations operations) throws DataAccessException {
operations.multi();
operations.opsForSet().add("key", "value1");
// This will contain the results of all operations in the transaction
return operations.exec();
}
});
System.out.println("Number of items added to set: " + txResults.get(0));
RedisTemplate
使用其 value、hash key 和 hash value 序列化器来反序列化 的所有结果。
还有一个额外的方法,允许你为交易结果传递一个自定义的序列化器。exec
exec
值得一提的是,如果 和 之间发生异常(例如,如果 Redis 在超时内没有响应,则超时异常),则连接可能会卡在事务状态。
为了防止这种情况,需要丢弃事务状态以清除连接:multi()
exec()
List<Object> txResults = redisOperations.execute(new SessionCallback<List<Object>>() {
public List<Object> execute(RedisOperations operations) throws DataAccessException {
boolean transactionStateIsActive = true;
try {
operations.multi();
operations.opsForSet().add("key", "value1");
// This will contain the results of all operations in the transaction
return operations.exec();
} catch (RuntimeException e) {
operations.discard();
throw e;
}
}
});
@Transactional
支持
默认情况下,不参与托管的 Spring 事务。
如果要在使用 或 时使用 Redis 事务,则需要通过设置 来显式启用每个事务支持。
启用事务支持将绑定到由 .
如果事务完成且没有错误,则 Redis 事务将使用 提交,否则使用 .
Redis 事务是面向批处理的。
在正在进行的事务期间发出的命令将排队,并且仅在提交事务时应用。RedisTemplate
RedisTemplate
@Transactional
TransactionTemplate
RedisTemplate
setEnableTransactionSupport(true)
RedisConnection
ThreadLocal
EXEC
DISCARD
Spring Data Redis 区分正在进行的事务中的只读命令和写入命令。
只读命令(如 )通过管道传输到新的(非线程绑定)以允许读取。
写入命令由 Submit 排队并在提交时应用。KEYS
RedisConnection
RedisTemplate
以下示例说明如何配置事务管理:
@Configuration
@EnableTransactionManagement (1)
public class RedisTxContextConfiguration {
@Bean
public StringRedisTemplate redisTemplate() {
StringRedisTemplate template = new StringRedisTemplate(redisConnectionFactory());
// explicitly enable transaction support
template.setEnableTransactionSupport(true); (2)
return template;
}
@Bean
public RedisConnectionFactory redisConnectionFactory() {
// jedis || Lettuce
}
@Bean
public PlatformTransactionManager transactionManager() throws SQLException {
return new DataSourceTransactionManager(dataSource()); (3)
}
@Bean
public DataSource dataSource() throws SQLException {
// ...
}
}
1 | 配置 Spring Context 以启用声明式事务 Management。 |
2 | 通过将连接绑定到当前线程来配置为参与事务。RedisTemplate |
3 | 事务管理需要 .
Spring Data Redis 不附带实现。
假设您的应用程序使用 JDBC,Spring Data Redis 可以使用现有的事务管理器参与事务。PlatformTransactionManager PlatformTransactionManager |
以下示例分别演示了使用约束:
// must be performed on thread-bound connection
template.opsForValue().set("thing1", "thing2");
// read operation must be run on a free (not transaction-aware) connection
template.keys("*");
// returns null as values set within a transaction are not visible
template.opsForValue().get("thing1");