ʲôÊÇ·Ö²¼Ê½Ëø?·Ö²¼Ê½ËøÊÇ¿ØÖÆ·Ö²¼Ê½ÏµÍ³Ö®¼äͬ²½·ÃÎʹ²Ïí×ÊÔ´µÄÒ»ÖÖ·½Ê½¡£ÔÚ·Ö²¼Ê½ÏµÍ³ÖУ¬³£³£ÐèҪе÷ËûÃǵĶ¯×÷¡£
ͼƬÀ´×Ô Pexels
Èç¹û²»Í¬µÄϵͳ»òÊÇͬһ¸öϵͳµÄ²»Í¬Ö÷»úÖ®¼ä¹²ÏíÁËÒ»¸ö»òÒ»×é×ÊÔ´£¬ÄÇô·ÃÎÊÕâЩ×ÊÔ´µÄʱºò£¬ÍùÍùÐèÒª»¥³âÀ´·ÀÖ¹±Ë´Ë¸ÉÈÅÀ´±£Ö¤Ò»ÖÂÐÔ£¬ÔÚÕâÖÖÇé¿öÏ£¬±ãÐèҪʹÓõ½·Ö²¼Ê½Ëø¡£
ΪʲôҪʹÓ÷ֲ¼Ê½Ëø
ΪÁ˱£Ö¤Ò»¸ö·½·¨»òÊôÐÔÔڸ߲¢·¢Çé¿öϵÄͬһʱ¼äÖ»Äܱ»Í¬Ò»¸öÏß³ÌÖ´ÐС£
ÔÚ´«Í³µ¥ÌåÓ¦Óõ¥»ú²¿ÊðµÄÇé¿öÏ£¬¿ÉÒÔʹÓà Java ²¢·¢´¦ÀíÏà¹ØµÄ API(Èç ReentrantLock »ò Synchronized)½øÐл¥³â¿ØÖÆ;ÔÚµ¥»ú»·¾³ÖУ¬Java ÖÐÌṩÁ˺ܶಢ·¢´¦ÀíÏà¹ØµÄ API¡£
µ«ÊÇ£¬Ëæ×ÅÒµÎñ·¢Õ¹µÄÐèÒª£¬Ôµ¥Ìåµ¥»ú²¿ÊðµÄϵͳ±»ÑÝ»¯³É·Ö²¼Ê½¼¯ÈºÏµÍ³ºó£¬ÓÉÓÚ·Ö²¼Ê½ÏµÍ³¶àÏ̡߳¢¶à½ø³Ì²¢ÇÒ·Ö²¼ÔÚ²»Í¬»úÆ÷ÉÏ£¬Õ⽫ʹԵ¥»ú²¿ÊðÇé¿öϵIJ¢·¢¿ØÖÆËø²ßÂÔʧЧ£¬µ¥´¿µÄ Java API ²¢²»ÄÜÌṩ·Ö²¼Ê½ËøµÄÄÜÁ¦¡£
ΪÁ˽â¾öÕâ¸öÎÊÌâ¾ÍÐèÒªÒ»ÖÖ¿ç JVM µÄ»¥³â»úÖÆÀ´¿ØÖƹ²Ïí×ÊÔ´µÄ·ÃÎÊ£¬Õâ¾ÍÊÇ·Ö²¼Ê½ËøÒª½â¾öµÄÎÊÌâ!
¾Ù¸öÀý×Ó£º»úÆ÷ A£¬»úÆ÷ B ÊÇÒ»¸ö¼¯Èº¡£A£¬B Á½Ì¨»úÆ÷ÉϵijÌÐò¶¼ÊÇÒ»ÑùµÄ£¬¾ß±¸¸ß¿ÉÓÃÐÔÄÜ¡£
A£¬B »úÆ÷¶¼ÓÐÒ»¸ö¶¨Ê±ÈÎÎñ£¬Ã¿ÌìÍíÉÏÁ賿 2 µãÐèÒªÖ´ÐÐÒ»¸ö¶¨Ê±ÈÎÎñ£¬µ«ÊÇÕâ¸ö¶¨Ê±ÈÎÎñÖ»ÄÜÖ´ÐÐÒ»±é£¬·ñÔòµÄ»°¾Í»á±¨´í¡£
ÄÇ A£¬B Á½Ì¨»úÆ÷ÔÚÖ´ÐеÄʱºò£¬¾ÍÐèÒªÇÀËø£¬ËÇÀµ½Ëø£¬ËÖ´ÐУ¬ËÇÀ²»µ½£¬¾Í²»ÓÃÖ´ÐÐÁË!
ËøµÄ´¦Àí
ËøµÄ´¦Àí·½Ê½ÈçÏ£º
·Ö²¼Ê½ËøµÄʵÏÖ
·Ö²¼Ê½ËøµÄʵÏÖ·½Ê½ÈçÏ£º
Redis µÄ·Ö²¼Ê½Ëø
»ñÈ¡Ëø
ÔÚ set ÃüÁîÖУ¬ÓкܶàÑ¡Ïî¿ÉÒÔÓÃÀ´ÐÞ¸ÄÃüÁîµÄÐÐΪ£¬ÒÔÏÂÊÇ set ÃüÁî¿ÉÓÃÑ¡ÏîµÄ»ù±¾Óï·¨£º
- redis 127.0.0.1:6379>SET KEY VALUE [EX seconds] [PX milliseconds] [NX|XX]
- - EX seconds ÉèÖÃÖ¸¶¨µÄµ½ÆÚʱ¼ä(µ¥Î»ÎªÃë)
- - PX milliseconds ÉèÖÃÖ¸¶¨µÄµ½ÆÚʱ¼ä(µ¥Î»ºÁÃë)
- - NX: ½öÔÚ¼ü²»´æÔÚʱÉèÖüü
- - XX: Ö»ÓÐÔÚ¼üÒÑ´æÔÚʱÉèÖÃ
·½Ê½ 1£ºÍƽé
- private static final String LOCK_SUCCESS = "OK";
- private static final String SET_IF_NOT_EXIST = "NX";
- private static final String SET_WITH_EXPIRE_TIME = "PX";
- ublic static boolean getLock(JedisCluster jedisCluster, String lockKey, String requestId, int expireTime) {
- // NX: ±£Ö¤»¥³âÐÔ
- String result = jedisCluster.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
- if (LOCK_SUCCESS.equals(result)) {
- return true;
- }
- return false;
- }
·½Ê½ 2£º
- public static boolean getLock(String lockKey,String requestId,int expireTime) {
- Long result = jedis.setnx(lockKey, requestId);
- if(result == 1) {
- jedis.expire(lockKey, expireTime);
- return true;
- }
- return false;
- }
×¢Ò⣺Íƽ鷽ʽ 1£¬ÒòΪ·½Ê½ 2 ÖÐ setnx ºÍ expire ÊÇÁ½¸ö²Ù×÷£¬²¢²»ÊÇÒ»¸öÔ×Ó²Ù×÷£¬Èç¹û setnx ³öÏÖÎÊÌ⣬¾ÍÊdzöÏÖËÀËøµÄÇé¿ö£¬ËùÒÔÍƼö·½Ê½ 1¡£
ÊÍ·ÅËø
·½Ê½ 1£ºdel ÃüÁîʵÏÖ
- public static void releaseLock(String lockKey,String requestId) {
- if (requestId.equals(jedis.get(lockKey))) {
- jedis.del(lockKey);
- }
- }
·½Ê½ 2£ºRedis+Lua ½Å±¾ÊµÏÖ(ÍƼö)
- public static boolean releaseLock(String lockKey, String requestId) {
- String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return
- redis.call('del', KEYS[1]) else return 0 end";
- Object result = jedis.eval(script, Collections.singletonList(lockKey),
- Collections.singletonList(requestId));
- if (result.equals(1L)) {
- return true;
- }
- return false;
- }
Zookeeper µÄ·Ö²¼Ê½Ëø
Zookeeper ·Ö²¼Ê½ËøʵÏÖÔÀí
Àí½âÁËËøµÄÔÀíºó£¬¾Í»á·¢ÏÖ£¬Zookeeper ÌìÉú¾ÍÊÇÒ»¸±·Ö²¼Ê½ËøµÄÅß×Ó¡£
Ê×ÏÈ£¬Zookeeper µÄÿһ¸ö½Úµã£¬¶¼ÊÇÒ»¸öÌìÈ»µÄ˳Ðò·¢ºÅÆ÷¡£
ÔÚÿһ¸ö½ÚµãÏÂÃæ´´½¨×Ó½Úµãʱ£¬Ö»ÒªÑ¡ÔñµÄ´´½¨ÀàÐÍÊÇÓÐÐò(EPHEMERAL_SEQUENTIAL ÁÙʱÓÐÐò»òÕß PERSISTENT_SEQUENTIAL ÓÀ¾ÃÓÐÐò)ÀàÐÍ£¬ÄÇô£¬ÐµÄ×Ó½ÚµãºóÃ棬»á¼ÓÉÏÒ»¸ö´ÎÐò±àºÅ¡£
Õâ¸ö´ÎÐò±àºÅ£¬ÊÇÉÏÒ»¸öÉú³ÉµÄ´ÎÐò±àºÅ¼Ó 1£¬±ÈÈ磬´´½¨Ò»¸öÓÃÓÚ·¢ºÅµÄ½Úµã“/test/lock”£¬È»ºóÒÔËûΪ¸¸Ç׽ڵ㣬ÔÚÕâ¸ö¸¸½ÚµãÏÂÃæ´´½¨Ïàͬǰ׺µÄ×ӽڵ㡣
¼Ù¶¨ÏàͬµÄǰ׺Ϊ“/test/lock/seq-”£¬ÔÚ´´½¨×Ó½Úµãʱ£¬Í¬Ê±Ö¸Ã÷ÊÇÓÐÐòÀàÐÍ¡£
Èç¹ûÊǵÚÒ»¸ö´´½¨µÄ×ӽڵ㣬ÄÇôÉú³ÉµÄ×Ó½ÚµãΪ /test/lock/seq-0000000000£¬ÏÂÒ»¸ö½ÚµãÔòΪ /test/lock/seq-0000000001£¬ÒÀ´ÎÀàÍÆ£¬µÈµÈ¡£
Æä´Î£¬Zookeeper ½ÚµãµÄµÝÔöÐÔ£¬¿ÉÒԹ涨½Úµã±àºÅ×îСµÄÄǸö»ñµÃËø¡£
Ò»¸ö Zookeeper ·Ö²¼Ê½Ëø£¬Ê×ÏÈÐèÒª´´½¨Ò»¸ö¸¸½Úµã£¬¾¡Á¿Êdz־ýڵã(PERSISTENT ÀàÐÍ)£¬È»ºóÿ¸öÒª»ñµÃËøµÄÏ̶߳¼»áÔÚÕâ¸ö½ÚµãÏ´´½¨¸öÁÙʱ˳Ðò½Úµã£¬ÓÉÓÚÐòºÅµÄµÝÔöÐÔ£¬¿ÉÒԹ涨ÅźÅ×îСµÄÄǸö»ñµÃËø¡£
ËùÒÔ£¬Ã¿¸öÏß³ÌÔÚ³¢ÊÔÕ¼ÓÃËø֮ǰ£¬Ê×ÏÈÅжÏ×Ô¼ºÊÇÅźÅÊDz»Êǵ±Ç°×îС£¬Èç¹ûÊÇ£¬Ôò»ñÈ¡Ëø¡£
µÚÈý£¬Zookeeper µÄ½Úµã¼àÌý»úÖÆ£¬¿ÉÒÔ±£ÕÏÕ¼ÓÐËøµÄ·½Ê½ÓÐÐò¶øÇÒ¸ßЧ¡£
ÿ¸öÏß³ÌÇÀÕ¼Ëø֮ǰ£¬ÏÈÇÀºÅ´´½¨×Ô¼ºµÄ ZNode¡£Í¬Ñù£¬ÊÍ·ÅËøµÄʱºò£¬¾ÍÐèҪɾ³ýÇÀºÅµÄ Znode¡£
ÇÀºÅ³É¹¦ºó£¬Èç¹û²»ÊÇÅźÅ×îСµÄ½Úµã£¬¾Í´¦Óڵȴý֪ͨµÄ״̬¡£µÈ˵Ä֪ͨÄØ?²»ÐèÒªÆäËûÈË£¬Ö»ÐèÒªµÈÇ°Ò»¸ö Znode µÄ֪ͨ¾Í¿ÉÒÔÁË¡£
µ±Ç°Ò»¸ö Znode ɾ³ýµÄʱºò£¬¾ÍÊÇÂÖµ½ÁË×Ô¼ºÕ¼ÓÐËøµÄʱºò¡£µÚÒ»¸ö֪ͨµÚ¶þ¸ö¡¢µÚ¶þ¸ö֪ͨµÚÈý¸ö£¬»÷¹Ä´«»¨ËƵÄÒÀ´ÎÏòºó¡£
Zookeeper µÄ½Úµã¼àÌý»úÖÆ£¬¿ÉÒÔ˵Äܹ»·Ç³£ÍêÃÀµÄ£¬ÊµÏÖÕâÖÖ»÷¹Ä´«»¨ËƵÄÐÅÏ¢´«µÝ¡£
¾ßÌåµÄ·½·¨ÊÇ£¬Ã¿Ò»¸öµÈ֪ͨµÄ Znode ½Úµã£¬Ö»ÐèÒª¼àÌý linsten »òÕß watch ¼àÊÓÅźÅÔÚ×Ô¼ºÇ°ÃæÄǸö£¬¶øÇÒ½ô°¤ÔÚ×Ô¼ºÇ°ÃæµÄÄǸö½Úµã¡£
Ö»ÒªÉÏÒ»¸ö½Úµã±»É¾³ýÁË£¬¾Í½øÐÐÔÙÒ»´ÎÅжϣ¬¿´¿´×Ô¼ºÊDz»ÊÇÐòºÅ×îСµÄÄǸö½Úµã£¬Èç¹ûÊÇ£¬Ôò»ñµÃËø¡£
Ϊʲô˵ Zookeeper µÄ½Úµã¼àÌý»úÖÆ£¬¿ÉÒÔ˵ÊǷdz£ÍêÃÀÄØ?
Ò»ÌõÁúʽµÄÊ×βÏà½Ó£¬ºóÃæ¼àÊÓÇ°Ã棬¾Í²»ÅÂÖмä½Ø¶ÏÂð?±ÈÈ磬ÔÚ·Ö²¼Ê½»·¾³Ï£¬ÓÉÓÚÍøÂçµÄÔÒò£¬»òÕß·þÎñÆ÷¹ÒÁË»òÕßÆäËûµÄÔÒò£¬Èç¹ûÇ°ÃæµÄÄǸö½ÚµãûÄܱ»³ÌÐòɾ³ý³É¹¦£¬ºóÃæµÄ½Úµã²»¾ÍÓÀÔ¶µÈ´ýô?
Æäʵ£¬Zookeeper µÄÄÚ²¿»úÖÆ£¬Äܱ£Ö¤ºóÃæµÄ½ÚµãÄܹ»Õý³£µÄ¼àÌýµ½É¾³ýºÍ»ñµÃËø¡£
ÔÚ´´½¨È¡ºÅ½ÚµãµÄʱºò£¬¾¡Á¿´´½¨ÁÙʱ Znode ½Úµã¶ø²»ÊÇÓÀ¾Ã Znode ½Úµã¡£
Ò»µ©Õâ¸ö Znode µÄ¿Í»§¶ËÓë Zookeeper ¼¯Èº·þÎñÆ÷ʧȥÁªÏµ£¬Õâ¸öÁÙʱ Znode Ò²½«×Ô¶¯É¾³ý¡£ÅÅÔÚËüºóÃæµÄÄǸö½Úµã£¬Ò²ÄÜÊÕµ½É¾³ýʼþ£¬´Ó¶ø»ñµÃËø¡£
˵ Zookeeper µÄ½Úµã¼àÌý»úÖÆ£¬ÊǷdz£ÍêÃÀµÄ¡£»¹ÓÐÒ»¸öÔÒò¡£Zookeeper ÕâÖÖÊ×βÏà½Ó£¬ºóÃæ¼àÌýÇ°ÃæµÄ·½Ê½£¬¿ÉÒÔ±ÜÃâÑòȺЧӦ¡£
ËùνÑòȺЧӦ¾ÍÊÇÿ¸ö½Úµã¹Òµô£¬ËùÓнڵ㶼ȥ¼àÌý£¬È»ºó×ö³ö·´Ó³£¬ÕâÑù»á¸ø·þÎñÆ÷´øÀ´¾Þ´óѹÁ¦£¬ËùÒÔÓÐÁËÁÙʱ˳Ðò½Úµã£¬µ±Ò»¸ö½Úµã¹Òµô£¬Ö»ÓÐËüºóÃæµÄÄÇÒ»¸ö½Úµã²Å×ö³ö·´Ó³¡£
Zookeeper ·Ö²¼Ê½ËøʵÏÖʾÀý
Zookeeper ÊÇͨ¹ýÁÙʱ½ÚµãÀ´ÊµÏÖ·Ö²¼Ê½Ëø£º
- terruptedException e) {
- e.printStackTrace();
- }
- System.out.println("*********ÒµÎñ·½·¨½áÊø************\n");
- }
- // ÕâÀïʹÓÃ@Test»á±¨´í
- public static void main(String[] args) {
- // ¶¨ÒåÖØÊԵIJà²ßÂÔ 1000 µÈ´ýµÄʱ¼ä(ºÁÃë) 10 ÖØÊԵĴÎÊý
- RetryPolicy policy = new ExponentialBackoffRetry(1000, 10);
- // ¶¨ÒåzookeeperµÄ¿Í»§¶Ë
- CuratorFramework client = CuratorFrameworkFactory.builder()
- .connectString("10.231.128.95:2181,10.231.128.96:2181,10.231.128.97:2181")
- .retryPolicy(policy)
- .build();
- // Æô¶¯¿Í»§¶Ë
- client.start();
- // ÔÚzookeeperÖж¨ÒåÒ»°ÑËø
- final InterProcessMutex lock = new InterProcessMutex(client, "/mylock");
- //Æô¶¯ÊǸöÏß³Ì
- for (int i = 0; i <10; i++) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- // ÇëÇóµÃµ½µÄËø
- lock.acquire();
- printNumber();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- // ÊÍ·ÅËø
- try {
- lock.release();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }).start();
- }
- }
- }
»ùÓÚÊý¾ÝµÄ·Ö²¼Ê½Ëø
ÎÒÃÇÔÚÌÖÂÛʹÓ÷ֲ¼Ê½ËøµÄʱºòÍùÍùÊ×ÏÈÅųýµô»ùÓÚÊý¾Ý¿âµÄ·½°¸£¬±¾ÄܵĻá¾õµÃÕâ¸ö·½°¸²»¹»“¸ß¼¶”¡£
´ÓÐÔÄܵĽǶȿ¼ÂÇ£¬»ùÓÚÊý¾Ý¿âµÄ·½°¸ÐÔÄÜȷʵ²»¹»ÓÅÒ죬ÕûÌåÐÔÄܶԱȣº»º´æ>Zookeeper¡¢etcd>Êý¾Ý¿â¡£
Ò²ÓÐÈËÌá³ö»ùÓÚÊý¾Ý¿âµÄ·½°¸ÎÊÌâºÜ¶à£¬²»Ì«¿É¿¿¡£Êý¾Ý¿âµÄ·½°¸¿ÉÄܲ¢²»ÊʺÏÓÚƵ·±Ð´ÈëµÄ²Ù×÷¡£
ÏÂÃæÎÒÃÇÀ´Á˽âһϻùÓÚÊý¾Ý¿â(MySQL)µÄ·½°¸£¬Ò»°ã·ÖΪÈýÀࣺ
»ùÓÚ±í¼Ç¼
ҪʵÏÖ·Ö²¼Ê½Ëø£¬×î¼òµ¥µÄ·½Ê½¿ÉÄܾÍÊÇÖ±½Ó´´½¨Ò»ÕÅËø±í£¬È»ºóͨ¹ý²Ù×÷¸Ã±íÖеÄÊý¾ÝÀ´ÊµÏÖÁË¡£
µ±ÎÒÃÇÏëÒª»ñµÃËøµÄʱºò£¬¾Í¿ÉÒÔÔڸñíÖÐÔö¼ÓÒ»Ìõ¼Ç¼£¬ÏëÒªÊÍ·ÅËøµÄʱºò¾Íɾ³ýÕâÌõ¼Ç¼¡£
ΪÁ˸üºÃµÄÑÝʾ£¬ÎÒÃÇÏÈ´´½¨Ò»ÕÅÊý¾Ý¿â±í£¬²Î¿¼ÈçÏ£º
- CREATE TABLE `database_lock` (
- `id` BIGINT NOT NULL AUTO_INCREMENT,
- `resource` int NOT NULL COMMENT 'Ëø¶¨µÄ×ÊÔ´',
- `description` varchar(1024) NOT NULL DEFAULT "" COMMENT 'ÃèÊö',
- PRIMARY KEY (`id`),
- UNIQUE KEY `uiq_idx_resource` (`resource`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Êý¾Ý¿â·Ö²¼Ê½Ëø±í';
¢Ù»ñµÃËø
ÎÒÃÇ¿ÉÒÔ²åÈëÒ»ÌõÊý¾Ý£º
- INSERT INTO database_lock(resource, description) VALUES (1, 'lock');
ÒòΪ±í database_lock ÖÐ resource ÊÇΨһË÷Òý£¬ËùÒÔÆäËûÇëÇóÌá½»µ½Êý¾Ý¿â£¬¾Í»á±¨´í£¬²¢²»»á²åÈë³É¹¦£¬Ö»ÓÐÒ»¸ö¿ÉÒÔ²åÈë¡£²åÈë³É¹¦£¬ÎÒÃǾͻñÈ¡µ½Ëø¡£
¢Úɾ³ýËø
- INSERT INTO database_lock(resource, description) VALUES (1, 'lock');
ÕâÖÖʵÏÖ·½Ê½·Ç³£µÄ¼òµ¥£¬µ«ÊÇÐèҪעÒâÒÔϼ¸µã£º
¢ÙÕâÖÖËøûÓÐʧЧʱ¼ä£¬Ò»µ©ÊÍ·ÅËøµÄ²Ù×÷ʧ°Ü¾Í»áµ¼ÖÂËø¼Ç¼һֱÔÚÊý¾Ý¿âÖУ¬ÆäËûÏß³ÌÎÞ·¨»ñµÃËø¡£Õâ¸öȱÏÝÒ²ºÜºÃ½â¾ö£¬±ÈÈç¿ÉÒÔ×öÒ»¸ö¶¨Ê±ÈÎÎñÈ¥¶¨Ê±ÇåÀí¡£
¢ÚÕâÖÖËøµÄ¿É¿¿ÐÔÒÀÀµÓÚÊý¾Ý¿â¡£½¨ÒéÉèÖñ¸¿â£¬±ÜÃâµ¥µã£¬½øÒ»²½Ìá¸ß¿É¿¿ÐÔ¡£
¢ÛÕâÖÖËøÊÇ·Ç×èÈûµÄ£¬ÒòΪ²åÈëÊý¾Ýʧ°ÜÖ®ºó»áÖ±½Ó±¨´í£¬ÏëÒª»ñµÃËø¾ÍÐèÒªÔٴβÙ×÷¡£
Èç¹ûÐèÒª×èÈûʽµÄ£¬¿ÉÒÔŪ¸ö for Ñ»·¡¢while Ñ»·Ö®ÀàµÄ£¬Ö±ÖÁ INSERT ³É¹¦ÔÙ·µ»Ø¡£
¢ÜÕâÖÖËøÒ²ÊÇ·Ç¿ÉÖØÈëµÄ£¬ÒòΪͬһ¸öÏß³ÌÔÚûÓÐÊÍ·ÅËø֮ǰÎÞ·¨ÔٴλñµÃËø£¬ÒòΪÊý¾Ý¿âÖÐÒѾ´æÔÚͬһ·Ý¼Ç¼ÁË¡£
ÏëҪʵÏÖ¿ÉÖØÈëËø£¬¿ÉÒÔÔÚÊý¾Ý¿âÖÐÌí¼ÓһЩ×ֶΣ¬±ÈÈç»ñµÃËøµÄÖ÷»úÐÅÏ¢¡¢Ïß³ÌÐÅÏ¢µÈ¡£
ÄÇôÔÚÔٴλñµÃËøµÄʱºò¿ÉÒÔÏȲéѯÊý¾Ý£¬Èç¹ûµ±Ç°µÄÖ÷»úÐÅÏ¢ºÍÏß³ÌÐÅÏ¢µÈÄܱ»²éµ½µÄ»°£¬¿ÉÒÔÖ±½Ó°ÑËø·ÖÅä¸øËü¡£
ÀÖ¹ÛËø
¹ËÃû˼Ò壬ϵͳÈÏΪÊý¾ÝµÄ¸üÐÂÔÚ´ó¶àÊýÇé¿öÏÂÊDz»»á²úÉú³åÍ»µÄ£¬Ö»ÔÚÊý¾Ý¿â¸üвÙ×÷Ìá½»µÄʱºò²Å¶ÔÊý¾Ý×÷³åÍ»¼ì²â¡£Èç¹û¼ì²âµÄ½á¹û³öÏÖÁËÓëÔ¤ÆÚÊý¾Ý²»Ò»ÖµÄÇé¿ö£¬Ôò·µ»Øʧ°ÜÐÅÏ¢¡£
ÀÖ¹ÛËø´ó¶àÊýÊÇ»ùÓÚÊý¾Ý°æ±¾(version)µÄ¼Ç¼»úÖÆʵÏֵġ£ºÎνÊý¾Ý°æ±¾ºÅ?
¼´ÎªÊý¾ÝÔö¼ÓÒ»¸ö°æ±¾±êʶ£¬ÔÚ»ùÓÚÊý¾Ý¿â±íµÄ°æ±¾½â¾ö·½°¸ÖУ¬Ò»°ãÊÇͨ¹ýΪÊý¾Ý¿â±íÌí¼ÓÒ»¸ö “version”×Ö¶ÎÀ´ÊµÏÖ¶ÁÈ¡³öÊý¾Ýʱ£¬½«´Ë°æ±¾ºÅһͬ¶Á³ö£¬Ö®ºó¸üÐÂʱ£¬¶Ô´Ë°æ±¾ºÅ¼Ó 1¡£
ÔÚ¸üйý³ÌÖУ¬»á¶Ô°æ±¾ºÅ½øÐбȽϣ¬Èç¹ûÊÇÒ»Öµģ¬Ã»Óз¢Éú¸Ä±ä£¬Ôò»á³É¹¦Ö´Ðб¾´Î²Ù×÷;Èç¹û°æ±¾ºÅ²»Ò»Ö£¬Ôò»á¸üÐÂʧ°Ü¡£
ΪÁ˸üºÃµÄÀí½âÊý¾Ý¿âÀÖ¹ÛËøÔÚʵ¼ÊÏîÄ¿ÖеÄʹÓã¬ÕâÀïÒ²¾Í¾ÙÁËÒµ½çÀÏÉú³£Ì¸µÄ¿â´æÀý×Ó¡£
Ò»¸öµçÉÌƽ̨¶¼»á´æÔÚÉÌÆ·µÄ¿â´æ£¬µ±Óû§½øÐйºÂòµÄʱºò¾Í»á¶Ô¿â´æ½øÐвÙ×÷(¿â´æ¼õ 1 ´ú±íÒѾÂô³öÁËÒ»¼þ)¡£
Èç¹ûÖ»ÊÇÒ»¸öÓû§½øÐвÙ×÷Êý¾Ý¿â±¾Éí¾ÍÄܱ£Ö¤Óû§²Ù×÷µÄÕýÈ·ÐÔ£¬¶øÔÚ²¢·¢µÄÇé¿öϾͻá²úÉúһЩÒâÏë²»µ½µÄÎÊÌâ¡£
±ÈÈçÁ½¸öÓû§Í¬Ê±¹ºÂòÒ»¼þÉÌÆ·£¬ÔÚÊý¾Ý¿â²ãÃæʵ¼Ê²Ù×÷Ó¦¸ÃÊÇ¿â´æ½øÐмõ 2 ²Ù×÷¡£
µ«ÊÇÓÉÓڸ߲¢·¢µÄÇé¿ö£¬µÚÒ»¸öÓû§¹ºÂòÍê³É½øÐÐÊý¾Ý¶ÁÈ¡µ±Ç°¿â´æ²¢½øÐмõ 1 ²Ù×÷£¬ÓÉÓÚÕâ¸ö²Ù×÷ûÓÐÍêÈ«Ö´ÐÐÍê³É¡£
µÚ¶þ¸öÓû§¾Í½øÈ빺ÂòÏàͬÉÌÆ·£¬´Ëʱ²éѯ³öµÄ¿â´æ¿ÉÄÜÊÇδ¼õ 1 ²Ù×÷µÄ¿â´æµ¼ÖÂÁËÔàÊý¾ÝµÄ³öÏÖ¡¾Ï̲߳»°²È«²Ù×÷¡¿¡£
Êý¾Ý¿âÀÖ¹ÛËøÒ²Äܱ£Ö¤Ḭ̈߳²È«£¬Í¨³£´úÂë²ãÃæÎÒÃǶ¼»áÕâÑù×ö£º
- select goods_num from goods where goods_name = "С±¾×Ó";
- update goods set goods_num = goods_num -1 where goods_name = "С±¾×Ó";
ÉÏÃæµÄ SQL ÊÇÒ»×éµÄ£¬Í¨³£ÏȲéѯ³öµ±Ç°µÄ goods_num£¬È»ºóÔÙ goods_num ÉϽøÐмõ 1 µÄ²Ù×÷Ð޸Ŀâ´æ¡£
µ±²¢·¢µÄÇé¿öÏ£¬ÕâÌõÓï¾ä¿ÉÄܵ¼ÖÂÔ±¾¿â´æΪ 3 µÄÒ»¸öÉÌÆ·¾¹ýÁ½¸öÈ˹ºÂò»¹Ê£Ï 2 ¿â´æµÄÇé¿ö¾Í»áµ¼ÖÂÉÌÆ·µÄ¶àÂô¡£ÄÇôÊý¾Ý¿âÀÖ¹ÛËøÊÇÈçºÎʵÏÖµÄÄØ?
Ê×Ïȶ¨ÒåÒ»¸ö version ×Ö¶ÎÓÃÀ´µ±×÷Ò»¸ö°æ±¾ºÅ£¬Ã¿´ÎµÄ²Ù×÷¾Í»á±ä³ÉÕâÑù£º
- select goods_num,version from goods where goods_name = "С±¾×Ó";
- update goods set goods_num = goods_num -1,version =²éѯµÄversionÖµ×ÔÔö where goods_name ="С±¾×Ó" and version=²éѯ³öÀ´µÄversion£»
Æäʵ£¬½èÖú¸üÐÂʱ¼ä´Á(updated_at)Ò²¿ÉÒÔʵÏÖÀÖ¹ÛËø£¬ºÍ²ÉÓà version ×ֶεķ½Ê½ÏàËÆ¡£
¸üвÙ×÷Ö´ÐÐÇ°Ïß»ñÈ¡¼Ç¼µ±Ç°µÄ¸üÐÂʱ¼ä£¬ÔÚÌá½»¸üÐÂʱ£¬¼ì²âµ±Ç°¸üÐÂʱ¼äÊÇ·ñÓë¸üпªÊ¼Ê±»ñÈ¡µÄ¸üÐÂʱ¼ä´ÁÏàµÈ¡£
±¯¹ÛËø
³ýÁË¿ÉÒÔͨ¹ýÔöɾ²Ù×÷Êý¾Ý¿â±íÖеļǼÒÔÍ⣬ÎÒÃÇ»¹¿ÉÒÔ½èÖúÊý¾Ý¿âÖÐ×Ô´øµÄËøÀ´ÊµÏÖ·Ö²¼Ê½Ëø¡£
ÔÚ²éѯÓï¾äºóÃæÔö¼Ó FOR UPDATE£¬Êý¾Ý¿â»áÔÚ²éѯ¹ý³ÌÖиøÊý¾Ý¿â±íÔö¼Ó±¯¹ÛËø£¬Ò²³ÆÅÅËûËø¡£µ±Ä³Ìõ¼Ç¼±»¼ÓÉϱ¯¹ÛËøÖ®ºó£¬ÆäËüÏß³ÌÒ²¾ÍÎÞ·¨ÔÙ¸ÄÐÐÉÏÔö¼Ó±¯¹ÛËø¡£
±¯¹ÛËø£¬ÓëÀÖ¹ÛËøÏà·´£¬×ÜÊǼÙÉè×µÄÇé¿ö£¬ËüÈÏΪÊý¾ÝµÄ¸üÐÂÔÚ´ó¶àÊýÇé¿öÏÂÊÇ»á²úÉú³åÍ»µÄ¡£
ÔÚʹÓñ¯¹ÛËøµÄͬʱ£¬ÎÒÃÇÐèҪעÒâÒ»ÏÂËøµÄ¼¶±ð¡£MySQL InnoDB ÒýÆðÔÚ¼ÓËøµÄʱºò£¬Ö»ÓÐÃ÷È·µØÖ¸¶¨Ö÷¼ü(»òË÷Òý)µÄ²Å»áÖ´ÐÐÐÐËø (Ö»Ëøס±»Ñ¡È¡µÄÊý¾Ý)£¬·ñÔò MySQL ½«»áÖ´ÐбíËø(½«Õû¸öÊý¾Ý±íµ¥¸øËøס)¡£
ÔÚʹÓñ¯¹ÛËøʱ£¬ÎÒÃDZØÐë¹Ø±Õ MySQL Êý¾Ý¿âµÄ×Ô¶¯Ìá½»ÊôÐÔ(²Î¿¼ÏÂÃæµÄʾÀý)£¬ÒòΪ MySQL ĬÈÏʹÓà autocommit ģʽ¡£
Ò²¾ÍÊÇ˵£¬µ±ÄãÖ´ÐÐÒ»¸ö¸üвÙ×÷ºó£¬MySQL »áÁ¢¿Ì½«½á¹û½øÐÐÌá½»¡£
- mysql> SET AUTOCOMMIT = 0;
- Query OK, 0 rows affected (0.00 sec)
ÕâÑùÔÚʹÓà FOR UPDATE »ñµÃËøÖ®ºó¿ÉÒÔÖ´ÐÐÏàÓ¦µÄÒµÎñÂß¼£¬Ö´ÐÐÍêÖ®ºóÔÙʹÓà COMMIT À´ÊÍ·ÅËø¡£
ÎÒÃDz»·ÁÑØÓÃÇ°ÃæµÄ database_lock ±íÀ´¾ßÌå±íÊöÒ»ÏÂÓ÷¨¡£¼ÙÉèÓÐÒ»Ïß³ÌAÐèÒª»ñµÃËø²¢Ö´ÐÐÏàÓ¦µÄ²Ù×÷¡£
ÄÇôËüµÄ¾ßÌå²½ÖèÈçÏ£º
- STEP1 - »ñÈ¡Ëø£ºSELECT * FROM database_lock WHERE id = 1 FOR UPDATE;¡£
- STEP2 - Ö´ÐÐÒµÎñÂß¼¡£
- STEP3 - ÊÍ·ÅËø£ºCOMMIT¡£
×÷ÕߣºÁ辧
¼ò½é£ºÉú»îÖеĶÎ×ÓÊÖ£¬Ä¿Ç°¾ÍÖ°ÓÚÒ»¼ÒµØ²ú¹«Ë¾×ö DevOPS Ïà¹Ø¹¤×÷, ÔøÔÚ´óÐÍ»¥ÁªÍø¹«Ë¾×ö¸ß¼¶ÔËά¹¤³Ìʦ£¬ÊìϤ Linux ÔËά£¬Python ÔËά¿ª·¢£¬Java ¿ª·¢£¬DevOPS ³£Óÿª·¢×é¼þµÈ£¬¸öÈ˹«Öںţºstromling£¬»¶ÓÀ´ÁÃÎÒŶ!
GoÔÉú¾ÍÖ§³ÖÁ¬½ÓÊý¾Ý¿â£¬ËùÒÔÔÚʹÓà Golang ¿ª·¢Ê±£¬µ±ÐèÒªÊý¾Ý¿â½»»¥Ê±£¬¼´¿É...
3ÔÂ22ÈÕÏûÏ¢ Íâý Winfuture ±¨µÀ£¬´Ëǰ΢ÈíÃæÏò Insider Ô¤ÀÀÓû§¹«²¼ÁË Window...
ÕâЩÈÕ×ÓÒ»Ö±ÔÚ¼òÊéÉÏʹÓÃmarkdownд×÷£¬ÒѾ½¥½¥µÄ³ÕÃÔÓÚÕâÖÖ¼ò½à´¿´âµÄд×÷·½...
±¾ÎÄʵÀý½²ÊöÁËÕýÔò±í´ïʽÖеIJÙ×÷·û¼°ËµÃ÷¡£·ÖÏí¸ø´ó¼Ò¹©´ó¼Ò²Î¿¼£¬¾ßÌåÈçÏ£º ...
Greediness£¨Ì°À·ÐÍ£©£º×î´óÆ¥Åä X¡¢X*¡¢X+¡¢X{n£¬} ÊÇ×î´óÆ¥Åä¡£ÀýÈçÄãÒªÓà ¡°....
2ÔÂ23ÈÕÏûÏ¢ ¾ÝÍâý Windows Latest ½ñÈÕ±¨µÀ£¬½èÖú Windows 10 Sun Valley ¸üÐÂ...
ajax ʵÏÖÈý¼¶Áª¶¯£¬Ï൱ÓÚдÁËÒ»¸öС²å¼þ£¬ÓõÄʱºòÖ±½ÓÄùýÀ´ÓþͿÉÒÔÁË£¬ÕâÀï...
´ÓÁíһ̨»úÆ÷Éϸ´ÖƹýÀ´µÄÏîÄ¿£¬ÓÉÓÚÁ½Ì¨»úÆ÷µÄ¿âĿ¼²»Ò»Ö£¬µ¼ÖÂÁËstdio.hµÈºÜ...
ÏðƤ²ÁÒ»¸ö¶ºÈ¤µÄ»¥ÁªÍø¸ß¼¶Íø³æ¡£ ¹ÛÇ°ÌáÐѱ¾ÆªÎÄÕÂÉ漰֪ʶµã¾Þ´ó½¨ÒéÏÈÊÕ²ØÔÙ...
1 . Ä¿±ê ÑÝʾÏÂͼµÄgit reset ¸÷Ñ¡ÏîµÄЧ¹û¡£ 2. Git Reset²Ù×÷˵Ã÷ ͼÖÐ˵Ã÷£º...