redis事務控制(redis部分支持事務)


1.說明:現在假設有一個session要執行若干次的修改處理,就可以考慮將若干操作放到一個事務中,這樣處理可以讓這些操作儀器一起執行或一起取消。Redis中的事務控制沒有傳統SQL中的事務控制那樣智能,redis中事務控制是將所有可以執行的指令都進行執行,不能執行的指令報錯。

2.指令:

•  開啟事務:multi 

•  提交事務:exec

•  取消當前隊列的所有操作:discard

舉例說明:

eg1:
set age 18
multi
set age 99
get age   這時執行結果為18,因為事務開啟了,set age 99沒有提交。
exec

eg2:
set age 10
set info lee
multi
incr age
incr info(info是字符串不能執行自增操作)
exec
執行結果:age的會執行,而incr info的會報錯,這就體現出了不是一起成功一起失敗

eg3:
multi
set name zhangsan
getset age 18
這時會報錯,因為getset不是指令,這一組操作會全部失敗

•  監控一個或多個key:watch  類似樂觀鎖,配合multi使用,一直監控着有沒有人修改,如果中途有其他人修改則會提交失敗。

•  取消對所有key的監控:unwatch,如果watch時提交失敗,我們需要執行unwatch先取消監控,再執行watch再次監控,multi,最后再提交

3.redis事務的三個階段:開啟,入隊,執行

4.redis事務的三個特性:單獨的隔離操作,沒有隔離級別的概念,不保證原子性

3.lettuce事務控制:

 •  同步的事務處理機制

package com.yootk.lettuce.transaction;
import com.yootk.lettuce.util.RedisConnectionUtil;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;
import java.util.concurrent.TimeUnit;

public class SyncTransactionDemo {
    public static void main(String[] args) throws Exception {
        StatefulRedisConnection connection = RedisConnectionUtil.getConnection();   // 獲取連接
        RedisCommands commands = connection.sync();//  創建同步操作命令
        System.out.println("【開啟事務】開啟多行執行:" + commands.multi());
        System.out.println("【設置數據】" + commands.set("lee-msg","Hello World"));
        System.out.println("【設置數據】" + commands.set("black-msg","Black Face"));
        TimeUnit.SECONDS.sleep(10); // 追加一個延遲處理
        System.out.println("【事務提交】" + commands.exec()); // 執行多個語句
        RedisConnectionUtil.close();
    }

}

 •  異步的事務處理機制

package com.yootk.lettuce.transaction;
import com.yootk.lettuce.util.RedisConnectionUtil;
import io.lettuce.core.RedisFuture;
import io.lettuce.core.TransactionResult;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.api.sync.RedisCommands;
import java.util.concurrent.TimeUnit;

public class AsyncTransactionDemo {
    public static void main(String[] args) throws Exception {
        StatefulRedisConnection connection = RedisConnectionUtil.getConnection();   // 獲取連接
        RedisAsyncCommands commands = connection.async();   // 執行語句
        RedisFuture multi = commands.multi();// 開啟事務
        RedisFuture setCmdA = commands.set("lee-msg", "Hello World");
        RedisFuture setCmdB = commands.set("black-msg","Black Face") ;
        RedisFuture<TransactionResult> exec = commands.exec();  // 自動的執行事務提交
        System.out.println("【開啟事務】開啟多行執行:" + multi.get());
        System.out.println("【設置數據】" + setCmdA.get());
        System.out.println("【設置數據】" + setCmdB.get());
        TimeUnit.SECONDS.sleep(5); // 追加一個延遲處理
        System.out.println("【事務提交】" + exec.get()); // 返回執行結果
        RedisConnectionUtil.close();
    }

}
• 響應式的事務處理機制
package com.yootk.lettuce.transaction;
import com.yootk.lettuce.util.RedisConnectionUtil;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import java.util.concurrent.TimeUnit;

public class ReactiveTransactionDemo {
    public static void main(String[] args) throws Exception {
        StatefulRedisConnection connection = RedisConnectionUtil.getConnection();   // 獲取連接
        RedisReactiveCommands commands = connection.reactive();// 創建響應式命令
        commands.multi().subscribe(temp ->{
            System.out.println("【設置數據】" + commands.set("lee-msg", "Hello World").subscribe());
            System.out.println("【設置數據】" + commands.set("black-msg","Black Face").subscribe());
            try {
                TimeUnit.SECONDS.sleep(10); // 休眠10秒
            } catch (InterruptedException e) {
            }
            System.out.println("【事務提交】" + commands.exec().subscribe());
        }) ;
        TimeUnit.SECONDS.sleep(20); // 追加一個等待機制
        RedisConnectionUtil.close();
    }
}

4.SpringDataRedis事務控制:在SpringDataRedis里面,所有的數據庫操作都是通過RedisTemplate展開的,相應的事務處理也可以通過此類直接完成處理。

import java.util.concurrent.TimeUnit;
@ContextConfiguration(locations={"classpath:spring/*.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class TestRedisTemplateTransaction{
  @Autowired
  private RedisTemplate<String,String>    stringRedisTemplate;
  @Test
  public void testTransaction()throws Exception{
      this.stringRedisTemplate.setEnableTransactionSupport(true);//開啟事務支持
      this.stringRedisTemplate.multi();//開啟事務操作
      this.stringRedisTemplate.opsForValue().set("lee-msg","hello world");
      this.stringRedisTemplate.opsForValue().set("black-msg","black face");  
      TimeUnit.SECONDS.sleep(5);
      System.out.println("【執行事務】"+this.stringRedisTemplate.exec());//提交
  }
}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM