【Redis緩衝機制】詳解Java串連Redis_Jedis_事務_java

來源:互聯網
上載者:User

Jedis事務

我們使用JDBC串連Mysql的時候,每次執行sql語句之前,都需要開啟事務;在MyBatis中,也需要使用openSession()來擷取session事務對象,來進行sql執行、查詢等操作。當我們對資料庫的操作結束的時候,是事務對象負責關閉資料庫連接。

事務對象用於管理、執行各種資料庫操作的動作。它能夠開啟和關閉資料庫連接,執行sql語句,復原錯誤的操作。

我們的Redis也有交易管理對象,其位於redis.clients.jedis.Transaction下。

Jedis事務的相關代碼:

package cn.com.redis;  import redis.clients.jedis.Jedis; import redis.clients.jedis.Transaction;  public class Test7 {   public static void main(String[] args) {     Jedis jedis = new Jedis("192.168.248.129",6379);          Transaction transaction=jedis.multi();//返回一個事務控制對象          //預先在事務對象中裝入要執行的操作     transaction.set("k4", "v4");     transaction.set("k5", "v5");          transaction.exec();//執行   } } 

我們查看一下redis:

探索資料已經加入進去

我們把k4的value和k5的value改為“v44”和“v55”,然後在transaction.exec()語句後加入transaction.discard()語句:

package cn.com.redis;  import redis.clients.jedis.Jedis; import redis.clients.jedis.Transaction;  public class Test7 {   public static void main(String[] args) {     Jedis jedis = new Jedis("192.168.248.129",6379);          Transaction transaction=jedis.multi();//返回一個事務控制對象          //預先在事務對象中裝入要執行的操作     transaction.set("k4", "v44");     transaction.set("k5", "v55");      transaction.discard();//復原   } } 

會探索資料插入操作被復原,redis中那兩個值未被改變:

我們類比一個刷一次信用卡的交易,使用redis的事務來處理一些邏輯:

package cn.com.redis;  import redis.clients.jedis.Jedis; import redis.clients.jedis.Transaction;  public class TestTransaction {   //類比信用卡消費和還款   public static void main(String[] args) {     TestTransaction t = new TestTransaction();     boolean retValue = t.transMethod(100);     if(retValue){       System.out.println("使用信用卡消費成功!");     }else{       System.out.println("使用信用卡消費失敗!");     }        }    /**    * 通俗點講,watch命令就是標記一個鍵,如果標記了一個鍵,    * 在提交事務前如果該鍵被別人修改過,那事務就會失敗,這種情況通常可以在程式中    * 重新再嘗試一次。    *    * 首先標記了balance,然後檢查餘額是否足夠,不足就取消標幟,並不做扣減;    * 足夠的話,就啟動事務進行更新操作。    * 如果在此期間鍵balance被其他人修改,拿在提交事務(執行exec)時就會報錯,    * 程式中通常可以捕獲這類錯誤再重新執行一次,直到成功。    * */   private boolean transMethod(int amount) {          System.out.println("您使用信用卡預付款"+amount+"元");          Jedis jedis = new Jedis("192.168.248.129",6379);          int balance = 1000;//可用餘額     int debt;//欠額     int amtToSubtract = amount;//實刷額度          jedis.set("balance", String.valueOf(balance));     jedis.watch("balance");     //jedis.set("balance", "1100");//此句不該出現,為了類比其他程式已經修改了該條目     balance = Integer.parseInt(jedis.get("balance"));     if(balance < amtToSubtract){//可用餘額小於實刷金額,拒絕交易       jedis.unwatch();       System.out.println("可用餘額不足!");       return false;     }else{//可用餘額夠用的時候再去執行計費操作       System.out.println("計費transaction事務開始執行...");       Transaction transaction = jedis.multi();       transaction.decrBy("balance",amtToSubtract);//餘額減去amtToSubtract的錢數       transaction.incrBy("debt", amtToSubtract);//信用卡欠款增加amtToSubtract的錢數       transaction.exec();//執行事務       balance = Integer.parseInt(jedis.get("balance"));       debt = Integer.parseInt(jedis.get("debt"));       System.out.println("計費transaction事務執行結束...");              System.out.println("您的可用餘額:"+balance);       System.out.println("您目前欠款:"+debt);       return true;     }   }    } 

此代碼就是類比使用者使用信用卡刷了100元的東西,此時應該減去信用卡的可用餘額100元,增加100元的欠款。

運行結果:

redis的結果:

證明我們的操作是成功的。

加watch命令是為了在事務執行的過程中,防止其它的操作打斷事務,或者是影響事務的計算結果,導致“幻讀”、“髒資料”等異常情況的發生。watch命令建立了一個鍵,一旦發現執行過程中該鍵被別人修改過,那事務就會失敗,程式中通常可以捕獲這類錯誤再重新執行一次,直到成功。所以watch命令可以保證資料的同步安全。

為了證明watch命令的用途,我們把上面代碼裡面的jedis.set("balance", "1100");注釋釋放,然後transMethod方法拋出打斷異常:throws InterruptedException,main方法捕獲打斷異常,然後彈出相應警告框。

package cn.com.redis;  import java.util.List;  import redis.clients.jedis.Jedis; import redis.clients.jedis.Transaction;  public class TestTransaction {   //類比信用卡消費和還款   public static void main(String[] args) {     TestTransaction t = new TestTransaction();     boolean retValue=false;     boolean Interrupted = false;          try {       retValue = t.transMethod(100);     } catch (InterruptedException e) {       Interrupted = true;       System.out.println("事務被打斷,請重新執行!");     }finally{       if(retValue){         System.out.println("使用信用卡消費成功!");       }else{         if(!Interrupted){           System.out.println("使用信用卡消費失敗!餘額不足!");         }       }     }   }    /**    * 通俗點講,watch命令就是標記一個鍵,如果標記了一個鍵,    * 在提交事務前如果該鍵被別人修改過,那事務就會失敗,這種情況通常可以在程式中    * 重新再嘗試一次。    *    * 首先標記了balance,然後檢查餘額是否足夠,不足就取消標幟,並不做扣減;    * 足夠的話,就啟動事務進行更新操作。    * 如果在此期間鍵balance被其他人修改,拿在提交事務(執行exec)時就會報錯,    * 程式中通常可以捕獲這類錯誤再重新執行一次,直到成功。    * */   private boolean transMethod(int amount) throws InterruptedException{          System.out.println("您使用信用卡預付款"+amount+"元");          Jedis jedis = new Jedis("192.168.248.129",6379);          int balance = 1000;//可用餘額     int debt;//欠額     int amtToSubtract = amount;//實刷額度          jedis.set("balance", String.valueOf(balance));     jedis.watch("balance");     jedis.set("balance", "1100");//此句不該出現,為了類比其他程式已經修改了該條目     balance = Integer.parseInt(jedis.get("balance"));     if(balance < amtToSubtract){//可用餘額小於實刷金額,拒絕交易       jedis.unwatch();       System.out.println("可用餘額不足!");       return false;     }else{//可用餘額夠用的時候再去執行計費操作       System.out.println("計費transaction事務開始執行...");       Transaction transaction = jedis.multi();       transaction.decrBy("balance",amtToSubtract);//餘額減去amtToSubtract的錢數       transaction.incrBy("debt", amtToSubtract);//信用卡欠款增加amtToSubtract的錢數       List<Object> result = transaction.exec();//執行事務              if(result==null){//事務提交失敗,說明在執行期間資料被修改過                  System.out.println("計費transaction事務執行中斷...");         throw new InterruptedException();                }else{//事務提交成功         balance = Integer.parseInt(jedis.get("balance"));         debt = Integer.parseInt(jedis.get("debt"));         System.out.println("計費transaction事務執行結束...");                  System.out.println("您的可用餘額:"+balance);         System.out.println("您目前欠款:"+debt);                  return true;       }     }   }    } 

再運行一下,看一下效果:

這就說明了,如果在watch命令執行後和事務提交之前,如果資料發生了修改操作,事務執行就不會成功,此舉保證了資料的安全性。

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援雲棲社區。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.