gpt4 book ai didi

java - 如何以干净的方式在 Spring Data Redis 中实现事务?

转载 作者:IT王子 更新时间:2023-10-29 05:58:32 27 4
gpt4 key购买 nike

我正在关注可用的 RetwisJ 教程 here .在此我认为没有实现 Redis 事务。例如,在下面的函数中,如果中间发生了一些异常,数据将处于不一致的状态。我想知道如何在 Spring Data Redis 中将如下功能作为单个事务实现:

public String addUser(String name, String password) {
String uid = String.valueOf(userIdCounter.incrementAndGet());

// save user as hash
// uid -> user
BoundHashOperations<String, String, String> userOps = template.boundHashOps(KeyUtils.uid(uid));
userOps.put("name", name);
userOps.put("pass", password);
valueOps.set(KeyUtils.user(name), uid);

users.addFirst(name);
return addAuth(name);
}

这里userIdCountervalueOpsusers是在构造函数中初始化的。我遇到过this在文档中(第 4.8 节),但我无法弄清楚如何将它放入这个函数中,其中一些变量在函数外部初始化(请不要告诉我必须在我需要的每个函数中初始化这些变量交易!)。

PS:另外,Spring Data Redis 是否有可用的@Transaction 注解或事务管理器?

更新:我尝试过使用MULTIEXEC。我写的代码是为另一个项目写的,但是当它应用到这个问题上时,它会是这样的:

public String addMyUser(String name, String password) {
String uid = String.valueOf(userIdCounter.incrementAndGet());
template.execute(new SessionCallback<Object>() {
@Override
public <K, V> Object execute(RedisOperations<K, V> operations)
throws DataAccessException {
operations.multi();
getUserOps(operations, KeyUtils.uid(uid)).put("name", name);
getUserOps(operations, KeyUtils.uid(uid)).put("pass", password);
getValueOps(operations).set(KeyUtils.user(name), uid);
getUserList(operations, KeyUtils.users()).leftPush(name);
operations.exec();
return null;
}
});
return addAuth(name);
}
private ValueOperations<String, String> getValueOps(RedisOperations operations) {
return operations.opsForValue();
}
private BoundHashOperations<String, String, String> getUserOps(RedisOperations operations, String key) {
return operations.boundHashOps(key);
}
private BoundListOperations<String, String> getUserList(RedisOperations operations, String key) {
return operations.boundListOps(key);
}

请告知是否推荐使用MULTIEXEC这种方式。

最佳答案

在 SD Redis 1.2 之前,您必须使用 TransactionSynchronisationManager 自行处理事务处理

上面的代码片段看起来像这样:

public String addUser(String name, String password) {

String uid = String.valueOf(userIdCounter.incrementAndGet());

// start the transaction
template.multi();

// register synchronisation
if(TransactionSynchronisationManager.isActualTransactionActive()) {
TransactionSynchronisationManager.registerSynchronisation(new TransactionSynchronizationAdapter()) {

@Override
public void afterCompletion(int status) {
switch(status) {
case STATUS_COMMITTED : template.exec(); break;
case STATUS_ROLLED_BACK : template.discard(); break;
default : template.discard();
}
}
}
}

BoundHashOperations<String, String, String> userOps = template.boundHashOps(KeyUtils.uid(uid));
userOps.put("name", name);
userOps.put("pass", password);
valueOps.set(KeyUtils.user(name), uid);

users.addFirst(name);

return addAuth(name);
}

请注意,一旦在 multi 中,读取操作也将成为事务的一部分,这意味着您可能无法从 redis 服务器读取数据。该设置可能与上述设置不同,因为您可能还想调用 WATCH。此外,您还必须注意多个回调,不要多次发送 MULTI 和/或 EXEC

即将发布的 1.3 版本的 Spring Data Redis 将以处理 MULTi|EXEC|DISCARD 的方式支持 spring 管理的事务,并允许在事务时进行读取操作(在现有键上)同步处于 Activity 状态。您已经可以试一试 BUILD-SNAPSHOT 并通过设置 template.setEnableTransactionSupport(true) 将其打开。

关于java - 如何以干净的方式在 Spring Data Redis 中实现事务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21664487/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com