Redis:解决分布式高并发修改同一个Key的问题( 二 )


A线程:
# 监视 key  , 且事务成功执行redis 127.0.0.1:6379> WATCH lock lock_timesOKredis 127.0.0.1:6379> MULTIOKredis 127.0.0.1:6379> SET lock "huangz"QUEUEDredis 127.0.0.1:6379> INCR lock_timesQUEUEDredis 127.0.0.1:6379> EXEC1) OK2) (integer) 1B线程:
# 监视 key  , 且事务被打断redis 127.0.0.1:6379> WATCH lock lock_timesOKredis 127.0.0.1:6379> MULTIOKredis 127.0.0.1:6379> SET lock "joe" # 就在这时 , 另一个客户端修改了 lock_times 的值QUEUEDredis 127.0.0.1:6379> INCR lock_timesQUEUEDredis 127.0.0.1:6379> EXEC # 因为 lock_times 被修改 ,  joe 的事务执行失败(nil)上边演示了A、B线程并发下的watch+mutil操作情况 。
解决高并发下修改同一个key遇到的问题:
package com.dx.es;import java.util.List;import java.util.concurrent.CountDownLatch;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;import redis.clients.jedis.Transaction;public class Test_Lock3 { public static void main(String[] args) { final JedisPool pool = RedisUtil.getPool(); // 对测试key赋初始值 Jedis jedis = pool.getResource(); jedis.hset("lock_test", "locker", "0"); String val = jedis.hget("lock_test", "locker"); System.out.println("lock_test.locker的初始值為:" + val); jedis.close(); int threahSize = 64; final CountDownLatch threadsCountDownLatch = new CountDownLatch(threahSize); Runnable handler = new Runnable() { public void run() { Jedis jedis = pool.getResource(); while (true) { jedis.watch("lock_test"); String val = jedis.hget("lock_test", "locker"); Integer integer = Integer.valueOf(val); Transaction tx = jedis.multi(); tx.hset("lock_test", "locker", String.valueOf(integer + 1)); List<Object> exec = tx.exec(); if (exec == null || exec.isEmpty()) { System.out.println(Thread.currentThread().getName() + ":" + "Error:(" + val + "=>" + (integer + 1) + ")"); } else { String values = ""; for (int i = 0; i < exec.size(); i++) { values += exec.get(i).toString(); } System.out.println(Thread.currentThread().getName() + ":" + values + ":(" + val + "=>" + (integer + 1) + ")"); break; } try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } jedis.close(); threadsCountDownLatch.countDown(); } }; for (int i = 0; i < threahSize; i++) { new Thread(handler).start(); } // 等待所有并行子线程任务完成 。try { threadsCountDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("complete"); val = jedis.hget("lock_test", "locker"); System.out.println(val); }}打印结果:
lock_test.locker的初始值為:0Thread-8:0:(0=>1)Thread-56:Error:(1=>2)Thread-53:0:(1=>2)Thread-25:Error:(0=>1)Thread-18:Error:(0=>1)Thread-3:Error:(0=>1)Thread-30:Error:(2=>3)Thread-11:Error:(2=>3)Thread-9:Error:(0=>1)Thread-63:0:(2=>3)Thread-7:Error:(0=>1)Thread-10:0:(3=>4)Thread-34:0:(4=>5)Thread-65:Error:(4=>5)Thread-24:Error:(0=>1)Thread-17:Error:(0=>1)Thread-62:0:(5=>6)Thread-29:Error:(6=>7)Thread-61:0:(6=>7)Thread-64:0:(7=>8)Thread-16:Error:(0=>1)Thread-19:Error:(8=>9)Thread-6:Error:(0=>1)Thread-28:Error:(0=>1)Thread-21:Error:(0=>1)Thread-14:Error:(0=>1)Thread-20:Error:(0=>1)Thread-5:Error:(0=>1)Thread-13:Error:(0=>1)Thread-15:Error:(0=>1)Thread-22:Error:(0=>1)Thread-4:Error:(0=>1)Thread-12:Error:(0=>1)Thread-23:Error:(0=>1)Thread-54:Error:(0=>1)Thread-57:Error:(0=>1)Thread-26:0:(8=>9)Thread-27:Error:(8=>9)Thread-32:Error:(9=>10)Thread-35:Error:(9=>10)Thread-56:0:(9=>10)Thread-33:Error:(10=>11)Thread-50:0:(10=>11)Thread-31:0:(11=>12)Thread-38:0:(12=>13)Thread-25:Error:(13=>14)Thread-36:0:(13=>14)Thread-39:Error:(14=>15)Thread-14:0:(14=>15)Thread-19:Error:(14=>15)Thread-17:Error:(14=>15)Thread-6:Error:(14=>15)Thread-9:Error:(14=>15)Thread-33:Error:(14=>15)Thread-35:Error:(14=>15)Thread-23:Error:(14=>15)Thread-18:Error:(14=>15)Thread-15:Error:(14=>15)Thread-11:Error:(14=>15)Thread-7:Error:(14=>15)Thread-57:Error:(14=>15)Thread-27:Error:(14=>15)Thread-16:Error:(14=>15)Thread-65:Error:(14=>15)Thread-24:Error:(14=>15)Thread-13:Error:(14=>15)Thread-32:Error:(15=>16)Thread-28:Error:(14=>15)Thread-21:Error:(14=>15)Thread-30:Error:(14=>15)Thread-54:Error:(14=>15)Thread-22:Error:(14=>15)Thread-25:Error:(14=>15)Thread-3:Error:(14=>15)Thread-29:Error:(14=>15)Thread-5:Error:(14=>15)Thread-12:Error:(14=>15)Thread-20:Error:(14=>15)Thread-40:0:(15=>16)Thread-4:Error:(14=>15)Thread-41:0:(16=>17)Thread-44:0:(17=>18)Thread-45:0:(18=>19)Thread-47:0:(19=>20)Thread-43:0:(20=>21)Thread-48:0:(21=>22)Thread-37:0:(22=>23)Thread-49:0:(23=>24)Thread-55:0:(24=>25)Thread-60:0:(25=>26)Thread-42:0:(26=>27)Thread-52:0:(27=>28)Thread-46:0:(28=>29)Thread-58:0:(29=>30)Thread-51:0:(30=>31)Thread-66:0:(31=>32)Thread-59:0:(32=>33)Thread-17:0:(33=>34)Thread-19:Error:(33=>34)Thread-39:Error:(33=>34)Thread-28:0:(34=>35)Thread-54:Error:(34=>35)Thread-65:Error:(34=>35)Thread-25:Error:(34=>35)Thread-30:Error:(34=>35)Thread-5:Error:(35=>36)Thread-13:Error:(35=>36)Thread-16:Error:(34=>35)Thread-6:Error:(34=>35)Thread-9:Error:(34=>35)Thread-21:Error:(35=>36)Thread-29:Error:(35=>36)Thread-33:Error:(34=>35)Thread-57:Error:(35=>36)Thread-24:Error:(34=>35)Thread-22:Error:(34=>35)Thread-32:Error:(35=>36)Thread-23:Error:(34=>35)Thread-7:Error:(34=>35)Thread-15:Error:(34=>35)Thread-4:0:(35=>36)Thread-20:Error:(35=>36)Thread-12:Error:(35=>36)Thread-35:0:(36=>37)Thread-18:Error:(36=>37)Thread-11:Error:(36=>37)Thread-3:Error:(36=>37)Thread-27:Error:(37=>38)Thread-39:Error:(37=>38)Thread-19:0:(37=>38)Thread-7:Error:(38=>39)Thread-33:0:(38=>39)Thread-29:Error:(38=>39)Thread-16:Error:(38=>39)Thread-22:Error:(38=>39)Thread-65:Error:(38=>39)Thread-54:Error:(38=>39)Thread-57:Error:(38=>39)Thread-30:Error:(38=>39)Thread-21:Error:(38=>39)Thread-24:Error:(38=>39)Thread-32:Error:(39=>40)Thread-5:Error:(39=>40)Thread-13:Error:(39=>40)Thread-6:Error:(38=>39)Thread-25:Error:(38=>39)Thread-9:Error:(38=>39)Thread-20:0:(39=>40)Thread-12:Error:(39=>40)Thread-15:Error:(38=>39)Thread-23:Error:(38=>39)Thread-18:Error:(40=>41)Thread-3:Error:(40=>41)Thread-27:0:(40=>41)Thread-11:Error:(40=>41)Thread-39:0:(41=>42)Thread-7:Error:(42=>43)Thread-54:0:(42=>43)Thread-22:Error:(42=>43)Thread-30:Error:(42=>43)Thread-57:Error:(42=>43)Thread-65:Error:(42=>43)Thread-32:Error:(43=>44)Thread-24:Error:(43=>44)Thread-5:Error:(42=>43)Thread-21:Error:(42=>43)Thread-16:Error:(43=>44)Thread-29:Error:(43=>44)Thread-6:0:(43=>44)Thread-9:Error:(43=>44)Thread-23:Error:(43=>44)Thread-25:Error:(43=>44)Thread-15:Error:(43=>44)Thread-12:Error:(43=>44)Thread-13:Error:(44=>45)Thread-11:0:(44=>45)Thread-18:Error:(44=>45)Thread-3:Error:(44=>45)Thread-57:0:(45=>46)Thread-7:Error:(45=>46)Thread-22:Error:(45=>46)Thread-30:Error:(45=>46)Thread-9:0:(46=>47)Thread-65:Error:(46=>47)Thread-25:Error:(46=>47)Thread-24:Error:(46=>47)Thread-21:Error:(47=>48)Thread-32:Error:(47=>48)Thread-5:Error:(47=>48)Thread-15:Error:(47=>48)Thread-16:0:(47=>48)Thread-29:Error:(47=>48)Thread-12:Error:(48=>49)Thread-23:Error:(47=>48)Thread-13:0:(48=>49)Thread-18:Error:(49=>50)Thread-3:Error:(49=>50)Thread-7:0:(49=>50)Thread-30:Error:(49=>50)Thread-22:Error:(49=>50)Thread-25:0:(50=>51)Thread-65:Error:(50=>51)Thread-12:0:(51=>52)Thread-21:Error:(51=>52)Thread-32:Error:(52=>53)Thread-24:Error:(52=>53)Thread-29:Error:(52=>53)Thread-5:Error:(52=>53)Thread-23:Error:(52=>53)Thread-15:Error:(52=>53)Thread-18:0:(52=>53)Thread-3:Error:(52=>53)Thread-30:0:(53=>54)Thread-22:Error:(53=>54)Thread-65:0:(54=>55)Thread-24:0:(55=>56)Thread-21:Error:(55=>56)Thread-32:Error:(55=>56)Thread-5:0:(56=>57)Thread-29:Error:(57=>58)Thread-15:0:(57=>58)Thread-23:Error:(57=>58)Thread-3:0:(58=>59)Thread-22:0:(59=>60)Thread-32:0:(60=>61)Thread-21:Error:(60=>61)Thread-29:0:(61=>62)Thread-23:Error:(61=>62)Thread-21:0:(62=>63)Thread-23:0:(63=>64)complete64


推荐阅读