乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      緩存對事務(wù)的支持

       xujin3 2018-06-17



      本文節(jié)選自即將出版的《可伸縮服務(wù)架構(gòu):框架與中間件》一書,作者:李艷鵬、楊彪、李海亮、賈博巖、劉淏。


      - 點擊文末原文鏈接可以直達《可伸縮服務(wù)架構(gòu):框架與中間件》書籍主頁。


      在使用Redis緩存的業(yè)務(wù)場景時經(jīng)常會有這樣的需求:要求遞減一個變量,如果遞減后變量小于等于0,則返回一個標志;如果成功,則返回剩余的值,類似于數(shù)據(jù)庫事務(wù)的實現(xiàn)。


      在實現(xiàn)中需要注意服務(wù)器端的多線程問題及客戶端的多線程問題。在服務(wù)器端可以利用服務(wù)器單線程執(zhí)行LUA腳本來保證,或者通過WATCHEXEC、DISCARD、EXEC來保證。


      Redis中支持LUA腳本,由于Redis使用單線程實現(xiàn),因此我們首先給出LUA腳本的實現(xiàn)方案。在如下代碼中,我們看到變量被遞減,并判斷是否將小于0的操作放到LUA腳本里,利用Redis的單線程執(zhí)行的特性完成這個原子遞減的操作:

      /**
      * Implemented by LUA. Minus a key by a value, then return the left value.
      * If the left value is less than 0, return -1; if error, return -1.
      *
      * @param key
      *            the key of the redis variable.
      * @param value
      *            the value to minus off.
      * @return the value left after minus. If it is less than 0, return -1; if
      *         error, return -1.
      */

      public long decrByUntil0Lua(String key, long value) {
         // If any error, return -1.
         if (value <=>0)
             return -1;

         // The logic is implemented in LUA script which is run in server thread,
         // which is single thread in one server.
         String script = ' local leftvalue = redis.call('get', KEYS[1]); '
                 + ' if ARGV[1] - leftvalue > 0 then return nil; else '
                 + ' return redis.call('decrby', KEYS[1], ARGV[1]); end; ';

         Long leftValue = (Long) jedis.eval(script, 1, key, '' + value);

         // If the left value is less than 0, return -1.
         if (leftValue == null)
             return -1;

         return leftValue;
      }

      還可以通過Redis對事務(wù)的支持方法watchmulti來實現(xiàn),類似于一個CAS方法的實現(xiàn),如果對熱數(shù)據(jù)有競爭,則會返回失敗,然后重試直到成功:

      /**
      * Implemented by CAS. Minus a key by a value, then return the left value.
      * If the left value is less than 0, return -1; if error, return -1.
      *
      * No synchronization, because redis client is not shared among multiple
      * threads.
      *
      * @param key
      *            the key of the redis variable.
      * @param value
      *            the value to minus off.
      * @return the value left after minus. If it is less than 0, return -1; if
      *         error, return -1.
      */

      public long decrByUntil0Cas(String key, long value) {
         // If any error, return -1.
         if (value <=>0)
             return -1;

         // Start the CAS operations.
         jedis.watch(key);

         // Start the transation.
         Transaction tx = jedis.multi();

         // Decide if the left value is less than 0, if no, terminate the
         // transation, return -1;
         String curr = tx.get(key).get();
         if (Long.valueOf(curr) - value <>0) {
             tx.discard();
             return -1;
         }

         // Minus the key by the value
         tx.decrBy(key, value);

         // Execute the transaction and then handle the result
         List result = tx.exec();

         // If error, return -1;
         if (result == null || result.isEmpty()) {
             return -1;
         }

         // Extract the first result
         for (Object rt : result) {
             return Long.valueOf(rt.toString());
         }

         // The program never comes here.
         return -1;
      }

      END


        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多