Spring-data-redis 2日目(トランザクション)
4453 ワード
今日から、Springのredisにおける様々な特性のサポート、事務、pipeline、sharding、cache、そして分布式やjedispoolなど、いろいろなことを学び始めました.頭が大きい.
1.まずJedis原生態の事務処理を見る
その中でJedisのwatch(key)で楽観的なロックを実現することができます.一つは、トランザクションプロセッサにエラーが発生しても、ロールバックされず、エラーが発生しても処理されません.Jedisのdiscardメソッドでトランザクションをキャンセルすることができます.自分でマルチスレッドをシミュレートして、この2つのメソッドの使用を見ることができます.もう一つは、トランザクションは非同期で実行されます.だからトランザクションでget同期クエリーの結果を呼び出すことはできません.ピットですね...
2.SpringでのRedisトランザクションのサポート
(1)
私たちは上の考えに従って、上のコードを書きました.そして間違ったことを報告しました:java.lang.NullPointerException,
次のコードを見てみましょう
このコードは実行に成功しました.なぜですか.Google大神たちだけがどう説明したのか.
まずソースコードを見ます.
ここでは、関数doInRedisが1つしかないRedisCallbackインタフェースを指定します.
doInRedisのパラメータはRedisConnectionインタフェースであり、spring-data-redisは非Redis Java Clientに対して対応するRedisConnectionを実現している.
JedisConnection
JredisConnection
RjcConnection
SrpConnection
目的は異なるClientのAPIを統一してアダプターと見なすことでしょう.
executeこれはテンプレート関数で、主に接続の問題を処理します.
Spring-data-redisは、非Redis Java Clientに対しても対応するRedisConnectionFactoryを実現し、接続を取得します.
例えばJedisConnectionFactory内部ではJedisPoolによる接続工場が実現されている.
通常、connectionが新しいたびに、前のコードのmultiが役に立たないことがわかります.
そうですか.私はコピーするのがおっくうで、この大神のブログを見てもいいです.http://jimgreat.iteye.com/blog/1596058セッションcallbackがセッションをどのように縛るかをよく話しています.
http://stackoverflow.com/questions/10750626/transactions-and-watch-statement-in-redisこの段落ではwatchの操作を説明していますが、よくわかります.
今日は忙しくて、事务を见るのが速いだけで、支持するのがあまりよくないと感じて、明日引き続き见て、顽张ります.
1.まずJedis原生態の事務処理を見る
Jedis jedis = new Jedis("192.168.137.100",6379);
Transaction tx = jedis.multi();
for(int i=0;i<1000; i++){
tx.set("zhang"+i, "hao"+i);
}
List<Object> result = tx.exec();
jedis.disconnect();
その中でJedisのwatch(key)で楽観的なロックを実現することができます.一つは、トランザクションプロセッサにエラーが発生しても、ロールバックされず、エラーが発生しても処理されません.Jedisのdiscardメソッドでトランザクションをキャンセルすることができます.自分でマルチスレッドをシミュレートして、この2つのメソッドの使用を見ることができます.もう一つは、トランザクションは非同期で実行されます.だからトランザクションでget同期クエリーの結果を呼び出すことはできません.ピットですね...
2.SpringでのRedisトランザクションのサポート
(1)
rt.watch("zhang");
rt.multi();
for(int i=0;i<10;i++){
BoundHashOperations<String, String, String> hs = rt.boundHashOps("zhang");
hs.put("zhang"+i, "hao"+i);
}
rt.exec();
私たちは上の考えに従って、上のコードを書きました.そして間違ったことを報告しました:java.lang.NullPointerException,
次のコードを見てみましょう
SessionCallback<String> sessionCallback = new SessionCallback<String>() {
@Override
public <K, V> String execute(RedisOperations<K, V> operation)
throws DataAccessException {
operation.multi();
for(int i=0;i<10;i++){
BoundHashOperations<String, String, String> hs = ((RedisTemplate)operation).boundHashOps("zhang");
hs.put("zhang"+i, "hao"+i);
}
operation.exec();
return null;
}
};
rt.execute(sessionCallback);
このコードは実行に成功しました.なぜですか.Google大神たちだけがどう説明したのか.
まずソースコードを見ます.
public void multi() {
execute(new RedisCallback<Object>() {
public Object doInRedis(RedisConnection connection) throws DataAccessException {
connection.multi();
return null;
}
}, true);
}
ここでは、関数doInRedisが1つしかないRedisCallbackインタフェースを指定します.
doInRedisのパラメータはRedisConnectionインタフェースであり、spring-data-redisは非Redis Java Clientに対して対応するRedisConnectionを実現している.
JedisConnection
JredisConnection
RjcConnection
SrpConnection
目的は異なるClientのAPIを統一してアダプターと見なすことでしょう.
executeこれはテンプレート関数で、主に接続の問題を処理します.
Spring-data-redisは、非Redis Java Clientに対しても対応するRedisConnectionFactoryを実現し、接続を取得します.
例えばJedisConnectionFactory内部ではJedisPoolによる接続工場が実現されている.
public <T> T execute(RedisCallback<T> action, boolean exposeConnection, boolean pipeline) {
Assert.notNull(action, "Callback object must not be null");
RedisConnectionFactory factory = getConnectionFactory();
RedisConnection conn = RedisConnectionUtils.getConnection(factory);
boolean existingConnection = TransactionSynchronizationManager.hasResource(factory);
preProcessConnection(conn, existingConnection);
boolean pipelineStatus = conn.isPipelined();
if (pipeline && !pipelineStatus) {
conn.openPipeline();
}
try {
RedisConnection connToExpose = (exposeConnection ? conn : createRedisConnectionProxy(conn));
T result = action.doInRedis(connToExpose);
// close pipeline
if (pipeline && !pipelineStatus) {
conn.closePipeline();
}
// TODO: any other connection processing?
return postProcessResult(result, conn, existingConnection);
} finally {
RedisConnectionUtils.releaseConnection(conn, factory);
}
}
通常、connectionが新しいたびに、前のコードのmultiが役に立たないことがわかります.
そうですか.私はコピーするのがおっくうで、この大神のブログを見てもいいです.http://jimgreat.iteye.com/blog/1596058セッションcallbackがセッションをどのように縛るかをよく話しています.
http://stackoverflow.com/questions/10750626/transactions-and-watch-statement-in-redisこの段落ではwatchの操作を説明していますが、よくわかります.
今日は忙しくて、事务を见るのが速いだけで、支持するのがあまりよくないと感じて、明日引き続き见て、顽张ります.