久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

緩存對事務的支持

 xujin3 2018-06-17



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


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


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


在實現(xiàn)中需要注意服務器端的多線程問題及客戶端的多線程問題。在服務器端可以利用服務器單線程執(zhí)行LUA腳本來保證,,或者通過WATCH,、EXECDISCARD,、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對事務的支持方法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)絡存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導購買等信息,,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多