ここで利用可能な RetwisJ チュートリアルに従っています。これでは、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);
}
ここでuserIdCounter
、valueOps
とusers
はコンストラクターで初期化されます。ドキュメント (セクション 4.8) でこれに遭遇しましたが、いくつかの変数が関数の外部で初期化されるこの関数にそれを適合させる方法がわかりません (これらの変数をそれぞれで初期化する必要があるとは言わないでください)。トランザクションが必要なすべての関数!)。
PS:また@Transaction
、Spring Data Redis で使用できるアノテーションまたはトランザクション マネージャーはありますか?
更新:を使用してみましMULTI
たEXEC
。私が書いたコードは別のプロジェクト用ですが、この問題に適用すると次のようになります。
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);
}
この の使い方がおすすめかどうか教えてMULTI
くださいEXEC
。