More Transactional Redis (1) - Redis is not a transactional storage
ãªãã¹ï¼ãªã©å«æç©ºï¼ã¿ããªå æ°ã«ãã¦ã£ãï¼
çªç¶ã ãã©ããªã©ãRedisã«ä¿åãã¦ããã¼ã¿ã«ä»¥ä¸ã®ãããªæä½ããã¦ã¿ãããªã£ã¡ã¾ã£ããã ï¼ããæ¬ä¼¼ã³ã¼ããªï¼
1: score = ZSCORE {key} {member} 2: if ( ! score ) { 3: score = defaultScore 4: } 5: ZADD {key} score + diff {member}
å ·ä½çãªå¦çã¯ä½ã§ããããã ãã©ãè¦ã¯ãZSCOREã§sorted setããscoreãåã£ã¦ããã®å¤ã«å¿ãã¦åå²ããä¸ã§ZADDã§å¤ãæ´æ°ããããã£ã¦ãã¨ã ãªï¼ä¸ã®å ´åã¯ZINCRBYã§ããããã©ãç´°ãããããæ°ã«ãããªï¼
...
ããã¾ã§èªãã§åã®ããèªè ãªãã°ãæ°ã¥ãã®ãã¨ã§ãããããä¸ã®æ¬ä¼¼ã³ã¼ãã«ã¯ããããrace conditionãåå¨ãã¾ããå®éã«ã¯ZSCORE, ZADDã®ã³ãã³ãã¯ãããããããã¯ã¼ã¯çµç±ã§Redisã«éãããå½ç¶ãªãããããã®å¦çã¯atomicã«ã¯è¡ãããªãããã以ä¸ã®æ§ãªã·ã¼ã±ã³ã¹ãæããã¾ãã
client A: 1ã§ZSCOREãçºè¡ client A: 2ã®ifæã§scoreããªãã¨å¤å® client B: 1ã§ZSCOREãçºè¡ client B: 2ã®ifæã§scoreããªãã¨å¤å® client A: 3ã§scoreã«defaultScoreãä»£å ¥ãã¦ã®ã¡ã5ã«é²ãã§ZADD client B: 3ã§scoreã«defaultScoreãä»£å ¥ãã¦ã®ã¡ã5ã«é²ãã§ZADD
ããã¯æã¾ããåä½ã§ã¯ããã¾ããã
MULTI - EXECã使ã
ããããªã®MULTIã§ããããããã¨æã£ãããã®ã¢ãã¿ï¼ããªãã®Redisåã¯1ã§ããMULTI - EXECã¯ãRediså´ã«ã³ãã³ãããã¥ã¼ã¤ã³ã°ãã¦ããã¦ãã¾ã¨ãã¦å®è¡ãããããã®ä»çµã¿ã§ãããªããããMULTIã®éä¸ã§Redisãããã¼ã¿ãåãåºãã¦ä¸èº«ãè¦ããã¨ã¯åºæ¥ã¾ããããã®ãããéä¸ã§ZSCOREããå¤ã«å¿ãã¦å¦çãåå²ãããã¨ãåºæ¥ã¾ããã
WATCHã使ã
ãWATCHãªãã©ãã ãããã¨æã£ãããã®ã¢ãã¿ï¼ããªãã®Redisåã¯3ã§ãããããæ®å¿µãªãããWATCHã使ããã®ã¯keyåä½ã§ã®ç£è¦ã®ã¿ã§ãããä»åã®ããã«keyã¨memberã®ä¸¡æ¹ã使ã£ã¦åç §ã»æ´æ°ãè¡ãSorted Setã«ã¤ãã¦ã¯ä½¿ãã¾ãããå³å¯ã«ã¯ä½¿ãããã¨ã¯ä½¿ããã®ã§ãããåãkeyå ã®å¥ã®memberã«å¯¾ããæ´æ°ããã£ãå ´åã§ãMULTI - EXECã®å®è¡å ¨ä½ã失æãã¦ãã¾ãã®ã§ã使ãç©ã«ãªãã¾ããã
é©å½ã«ããã¯ãã
ããããªã®ãä½ããã®middleware (Redisã®SETNXã§ããã) 使ã£ã¦ããã¯ãã©ããå®è£ ãã¦ãlockãåããªãã£ãã失æãããã°ããããããã¨æã£ãããã®ã¢ãã¿ï¼ããªãã®Redisåã¯â¦åããã¾ãããããããããã³ã¹ã®ç¥æ§ãªãã¬ããã¯ããªã¼ã®ç¥æ§ã«æããããã¨ã¯ééããªãã§ãã
Lua Scriptingã使ã
ããããªã®ãLua Scriptingã§å®è£ ããã°ããããããã¨æã£ãããã®ã¢ãã¿ï¼ããªãã®Redisåã¯5ã§ããLua Scripting on Redisã¯atomicã«å®è¡ããããããä»åã®è¦ä»¶ãæºããã¾ããããã¯ã使ãããããããå®è¡å¹çãããã§ãããã
ã§ããRedisã®Lua Scriptingãªãã¦æ©è½ã使ã£ããã¨ãªããã¼ï¼å¤§ä¸å¤«ããªï¼æ¬çªæå ¥ãã§ããããªï¼
ãã®è¨äºã¯ããããªããªãã®çåã«ãå¿ããã¾ããï¼ç¶ãï¼