StringRedisTemplateがトランザクションを開始します

SpringBootでRedisを使用する場合、次のredisスターター

org.springframework.boot
spring-boot-starter-data-redisを

導入します。このスターターは、redisコアを持つ2つのパッケージ、jedisとspring-data-redisを導入します。

Redisトランザクション関連のコマンドリファレンスSpringBootでの
トランザクション
Redisトランザクションの適用
注:以下は、SpringBootでのRedisトランザクションの正しい使用法と誤った使用法を示すためのテストケースです。まず、現在のテストケースのメインコードを見てみましょう。

パッケージcom.imooc.ad.service;

インポートcom.imooc.ad.Application;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;

/ **

  • Redisトランザクションテスト

  • Qinyiによって作成されました。
    * /
    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = {Application.class}、webEnvironment = SpringBootTest.WebEnvironment.NONE)
    public class RedisTransTest {

    / ** StringRedisTemplateを挿入し、デフォルト構成を使用します/
    @Autowired
    private StringRedisTemplatestringRedisTemplate;
    間違った使用法
    /
    *

  • トランザクションサポートがオンになっていません:トランザクションの実行は失敗します

  • * /
    @Test
    public void testMultiFailure(){

stringRedisTemplate.multi();
stringRedisTemplate.opsForValue()。set( "name"、 "qinyi");
stringRedisTemplate.opsForValue()。set( "gender"、 "male");
stringRedisTemplate.opsForValue()。set( "age ”、“ 19”);
System.out.println(stringRedisTemplate.exec());
}
上記のテストケースを実行すると、次の例外メッセージがスローされます。

実行中のエラー。ネストされた例外はio.lettuce.core.RedisCommandExecutionExceptionです:MULTIなしのERR EXEC
ここに表示されるエラーメッセージは次のとおりです。EXECコマンドを実行する前に、MULTIコマンドが実行されませんでした。これは非常に奇妙なことです。テストメソッドの最初の文でMULTIを実行したことは明らかです。multiやexecなどのメソッドをトレースすると、次の実行ソースコード(spring-data-redis)を確認できます。

public T execute(RedisCallbackアクション、ブール値exposeConnection、ブール値パイプライン){

Assert.isTrue(initialized、“テンプレートは初期化されていません。使用する前にafterPropertiesSet()を呼び出してください”);
Assert.notNull(action、“コールバックオブジェクトはnullであってはなりません”);

RedisConnectionFactoryファクトリ= getRequiredConnectionFactory();
RedisConnection conn = null;
試す{ // RedisTemplate的enableTransactionSupport属性标识是否开启了事务支持、默认是偽の場合(enableTransactionSupport){ 潜在的なトランザクション同期の場合は//のみバインドリソースCONN = RedisConnectionUtils.bindConnection(工場、enableTransactionSupport)。} else { conn = RedisConnectionUtils.getConnection(factory); }






 boolean existingConnection = TransactionSynchronizationManager.hasResource(factory);

答えはすでにソースコードに記載されています。enableTransactionSupport属性のデフォルト値がfalseであるため、各RedisConnectionが再取得されます。したがって、MULTIとEXECを実行したばかりの2つのコマンドは、同じ接続にありません。

enableTransactionSupportを設定してトランザクションサポートを有効にし
ます。上記の例の問題を解決する最も簡単な方法は、RedisTemplateを有効にしてトランザクションサポートを有効にすることです。つまり、enableTransactionSupportをtrueに設定します。テストコードは次のとおりです。

/**
 * <h2>开启事务支持: 成功执行事务</h2>
 * */
@Test
public void testMultiSuccess() {
  // 开启事务支持,在同一个 Connection 中执行命令
  stringRedisTemplate.setEnableTransactionSupport(true);

  stringRedisTemplate.multi();
  stringRedisTemplate.opsForValue().set("name", "qinyi");
  stringRedisTemplate.opsForValue().set("gender", "male");
  stringRedisTemplate.opsForValue().set("age", "19");
  System.out.println(stringRedisTemplate.exec());     // [true, true, true]
}

SessionCallbackを使用すると、すべての操作が同じセッションで完了することが保証されます。
より一般的な記述方法は、RedisTemplateのデフォルト構成を使用することです。つまり、トランザクションサポートを有効にしません。ただし、SessionCallbackを使用することはできます。これにより、すべての内部操作が同じセッションに確実に含まれるようになります。テストコードは次のとおりです。

/**
 * <h2>使用 SessionCallback, 在同一个 Redis Connection 中执行事务: 成功执行事务</h2>
 * */
@Test
@SuppressWarnings("all")
public void testSessionCallback() {

    SessionCallback<Object> callback = new SessionCallback<Object>() {
        @Override
        public Object execute(RedisOperations operations) throws DataAccessException {
            operations.multi();
            operations.opsForValue().set("name", "qinyi");
            operations.opsForValue().set("gender", "male");
            operations.opsForValue().set("age", "19");
            return operations.exec();
        }
    };

    // [true, true, true]
    System.out.println(stringRedisTemplate.execute(callback));
}

概要:SpringBootでRedisを操作する場合、RedisTemplateのデフォルト構成を使用すると、ほとんどのシナリオをすでに満たすことができます。トランザクション操作を実行する場合は、SessionCallbackを使用することをお勧めします。これも、一般的な選択です。

元のリンク:http://www.imooc.com/article/281310?block_id = tuijian_wz#

おすすめ

転載: blog.csdn.net/My_Way666/article/details/107067886