zoukankan      html  css  js  c++  java
  • Mysql锁机制--乐观锁 & 悲观锁

    第一部分 悲观锁

    1 概念(来自百科)

    悲观锁,正如其名,它指的是对数据被外界(包括当前系统的其它事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排它性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。

    还可以简单理解,就是Java中的 Synchronized 关键字。只要对代码加了 Synchronized 关键字,JVM 底层就能保证其线程安全性。

    那么,在 Mysql 中如何实现悲观锁呢?下面分别以命令行以及Java代码的方式进行演示。

    2 命令行演示

    2.1 准备数据

    复制代码
    DROP DATABASE IF EXISTS cyhTest;
    CREATE DATABASE cyhTest;
    
    USE cyhTest;
    
    DROP TABLE IF EXISTS employee;
    
    CREATE TABLE IF NOT EXISTS employee (
      id      INTEGER NOT NULL,
      money   INTEGER,
      version INTEGER,
      PRIMARY KEY (id)
    )
      ENGINE = INNODB;
    
    INSERT INTO employee VALUE (1, 0, 1);
    
    SELECT * FROM employee;
    复制代码

    目前数据库中只有一条记录,且初始Money=0

    2.2 测试

    测试准备:

    • 还是两个会话(终端),左边会话是白色背景、右边会话是黑色背景
    • 关闭自动提交:set autocommit = 0; 

    现在开始测试:

    第一步:两个终端均关闭自动提交

    左边:

    右边:

    第二步:左边利用 select .... for update 的悲观锁语法锁住记录

    select * from employee where id = 1 for update; 

    第三步:右边也尝试利用 select .... for update 的悲观锁语法锁住记录

    可以看到,Sql语句被挂起(被阻塞)!

    提示:如果被阻塞的时间太长,会提示如下:

    第四步:左边执行更新操作并提交事务

    Sql语句:

    update employee set money = 0 + 1 where id = 1;
    commit; 

    结果:

    分析:

    • Money 的旧值为0,所以更新时 Money=0+1
    • 一执行 commit 后,注意查看右边Sql语句的变化

    第五步:查看右边Sql语句的变化

    分析:

    • 被左边悲观锁阻塞了 11.33 秒
    • Money=1,这是左边更新后的结果

    2.3 结论

    可以看到,当左边(事务A)使用了 select ... for update 的悲观锁后,右边(事务B)再想使用将被阻塞,同时,阻塞被解除后事务B能看到事务A对数据的修改,所以,这就可以很好地解决并发事务的更新丢失问题啦(诚然,这也是人家悲观锁的分内事)

    3 Java代码演示

    Demo 代码地址:https://github.com/cyhbyw/cyh_Spring_IsolationConcurrencyTransaction

    Demo 工程名称:usingMybatis

    3.1 准备

    确保数据库用户名和密码对应;执行 test.sql 文件中的脚本;

    3.2 业务逻辑代码

    XML 文件中的 Mapper:

        <select id="findByIdWithPessimisticLock" resultType="com.cyh.entity.Employee">
            SELECT * FROM employee WHERE id = #{id} FOR UPDATE
        </select>

    提示:这里是 SELCT ... FOR UPDATE

    Service 中的业务逻辑:

    复制代码
    1     @Transactional(rollbackFor = RuntimeException.class)
    2     public void increaseMoneyWithPessimisticLock(Integer id) {
    3         Employee employee = employeeMapper.findByIdWithPessimisticLock(id);
    4         final Integer oldMoney = employee.getMoney();
    5         LOGGER.info("oldMoney: {}", oldMoney);
    6         employee.setMoney(oldMoney + 1);
    7         employeeMapper.updateEmployee(employee);
    8     }
    复制代码

    提示:第3行中的 findByIdWithPessimisticLock() 方法就对应上面XML文件中的Mapper,有悲观锁

    3.3 测试代码

        private void increaseMoneyWithPessimisticLock() {
            int threadCount = 100;
            while (threadCount-- > 0) {
                new Thread(() -> employeeService.increaseMoneyWithPessimisticLock(1)).start();
            }
        }

    提示:100根线程,每个线程将Money值加1,预期结果是100

    3.4 执行测试&查看结果

    SELECT * FROM employee;

    Money=100,是预期结果。

    3.5 查看日志

      1 2018-04-25 15:12:14,335  INFO [Thread-5] (EmployeeService.java:36) - oldMoney: 0
      2 2018-04-25 15:12:14,343  INFO [Thread-25] (EmployeeService.java:36) - oldMoney: 1
      3 2018-04-25 15:12:14,345  INFO [Thread-27] (EmployeeService.java:36) - oldMoney: 2
      4 2018-04-25 15:12:14,347  INFO [Thread-23] (EmployeeService.java:36) - oldMoney: 3
      5 2018-04-25 15:12:14,349  INFO [Thread-13] (EmployeeService.java:36) - oldMoney: 4
      6 2018-04-25 15:12:14,350  INFO [Thread-38] (EmployeeService.java:36) - oldMoney: 5
      7 2018-04-25 15:12:14,351  INFO [Thread-24] (EmployeeService.java:36) - oldMoney: 6
      8 2018-04-25 15:12:14,353  INFO [Thread-4] (EmployeeService.java:36) - oldMoney: 7
      9 2018-04-25 15:12:14,355  INFO [Thread-26] (EmployeeService.java:36) - oldMoney: 8
     10 2018-04-25 15:12:14,357  INFO [Thread-8] (EmployeeService.java:36) - oldMoney: 9
     11 2018-04-25 15:12:14,360  INFO [Thread-3] (EmployeeService.java:36) - oldMoney: 10
     12 2018-04-25 15:12:14,361  INFO [Thread-81] (EmployeeService.java:36) - oldMoney: 11
     13 2018-04-25 15:12:14,363  INFO [Thread-20] (EmployeeService.java:36) - oldMoney: 12
     14 2018-04-25 15:12:14,365  INFO [Thread-40] (EmployeeService.java:36) - oldMoney: 13
     15 2018-04-25 15:12:14,366  INFO [Thread-29] (EmployeeService.java:36) - oldMoney: 14
     16 2018-04-25 15:12:14,453  INFO [Thread-14] (EmployeeService.java:36) - oldMoney: 15
     17 2018-04-25 15:12:14,475  INFO [Thread-7] (EmployeeService.java:36) - oldMoney: 16
     18 2018-04-25 15:12:14,485  INFO [Thread-11] (EmployeeService.java:36) - oldMoney: 17
     19 2018-04-25 15:12:14,488  INFO [Thread-48] (EmployeeService.java:36) - oldMoney: 18
     20 2018-04-25 15:12:14,491  INFO [Thread-47] (EmployeeService.java:36) - oldMoney: 19
     21 2018-04-25 15:12:14,494  INFO [Thread-12] (EmployeeService.java:36) - oldMoney: 20
     22 2018-04-25 15:12:14,497  INFO [Thread-72] (EmployeeService.java:36) - oldMoney: 21
     23 2018-04-25 15:12:14,500  INFO [Thread-46] (EmployeeService.java:36) - oldMoney: 22
     24 2018-04-25 15:12:14,501  INFO [Thread-44] (EmployeeService.java:36) - oldMoney: 23
     25 2018-04-25 15:12:14,503  INFO [Thread-45] (EmployeeService.java:36) - oldMoney: 24
     26 2018-04-25 15:12:14,504  INFO [Thread-41] (EmployeeService.java:36) - oldMoney: 25
     27 2018-04-25 15:12:14,505  INFO [Thread-9] (EmployeeService.java:36) - oldMoney: 26
     28 2018-04-25 15:12:14,507  INFO [Thread-19] (EmployeeService.java:36) - oldMoney: 27
     29 2018-04-25 15:12:14,508  INFO [Thread-55] (EmployeeService.java:36) - oldMoney: 28
     30 2018-04-25 15:12:14,509  INFO [Thread-36] (EmployeeService.java:36) - oldMoney: 29
     31 2018-04-25 15:12:14,518  INFO [Thread-43] (EmployeeService.java:36) - oldMoney: 30
     32 2018-04-25 15:12:14,547  INFO [Thread-53] (EmployeeService.java:36) - oldMoney: 31
     33 2018-04-25 15:12:14,556  INFO [Thread-52] (EmployeeService.java:36) - oldMoney: 32
     34 2018-04-25 15:12:14,558  INFO [Thread-51] (EmployeeService.java:36) - oldMoney: 33
     35 2018-04-25 15:12:14,560  INFO [Thread-50] (EmployeeService.java:36) - oldMoney: 34
     36 2018-04-25 15:12:14,562  INFO [Thread-32] (EmployeeService.java:36) - oldMoney: 35
     37 2018-04-25 15:12:14,563  INFO [Thread-85] (EmployeeService.java:36) - oldMoney: 36
     38 2018-04-25 15:12:14,565  INFO [Thread-84] (EmployeeService.java:36) - oldMoney: 37
     39 2018-04-25 15:12:14,567  INFO [Thread-33] (EmployeeService.java:36) - oldMoney: 38
     40 2018-04-25 15:12:14,568  INFO [Thread-82] (EmployeeService.java:36) - oldMoney: 39
     41 2018-04-25 15:12:14,570  INFO [Thread-34] (EmployeeService.java:36) - oldMoney: 40
     42 2018-04-25 15:12:14,571  INFO [Thread-35] (EmployeeService.java:36) - oldMoney: 41
     43 2018-04-25 15:12:14,573  INFO [Thread-83] (EmployeeService.java:36) - oldMoney: 42
     44 2018-04-25 15:12:14,574  INFO [Thread-42] (EmployeeService.java:36) - oldMoney: 43
     45 2018-04-25 15:12:14,575  INFO [Thread-22] (EmployeeService.java:36) - oldMoney: 44
     46 2018-04-25 15:12:14,585  INFO [Thread-30] (EmployeeService.java:36) - oldMoney: 45
     47 2018-04-25 15:12:14,586  INFO [Thread-28] (EmployeeService.java:36) - oldMoney: 46
     48 2018-04-25 15:12:14,613  INFO [Thread-16] (EmployeeService.java:36) - oldMoney: 47
     49 2018-04-25 15:12:14,615  INFO [Thread-17] (EmployeeService.java:36) - oldMoney: 48
     50 2018-04-25 15:12:14,616  INFO [Thread-21] (EmployeeService.java:36) - oldMoney: 49
     51 2018-04-25 15:12:14,618  INFO [Thread-18] (EmployeeService.java:36) - oldMoney: 50
     52 2018-04-25 15:12:14,619  INFO [Thread-37] (EmployeeService.java:36) - oldMoney: 51
     53 2018-04-25 15:12:14,621  INFO [Thread-39] (EmployeeService.java:36) - oldMoney: 52
     54 2018-04-25 15:12:14,623  INFO [Thread-2] (EmployeeService.java:36) - oldMoney: 53
     55 2018-04-25 15:12:14,624  INFO [Thread-1] (EmployeeService.java:36) - oldMoney: 54
     56 2018-04-25 15:12:14,626  INFO [Thread-10] (EmployeeService.java:36) - oldMoney: 55
     57 2018-04-25 15:12:14,627  INFO [Thread-15] (EmployeeService.java:36) - oldMoney: 56
     58 2018-04-25 15:12:14,628  INFO [Thread-56] (EmployeeService.java:36) - oldMoney: 57
     59 2018-04-25 15:12:14,630  INFO [Thread-54] (EmployeeService.java:36) - oldMoney: 58
     60 2018-04-25 15:12:14,632  INFO [Thread-31] (EmployeeService.java:36) - oldMoney: 59
     61 2018-04-25 15:12:14,642  INFO [Thread-57] (EmployeeService.java:36) - oldMoney: 60
     62 2018-04-25 15:12:14,645  INFO [Thread-6] (EmployeeService.java:36) - oldMoney: 61
     63 2018-04-25 15:12:14,672  INFO [Thread-62] (EmployeeService.java:36) - oldMoney: 62
     64 2018-04-25 15:12:14,677  INFO [Thread-59] (EmployeeService.java:36) - oldMoney: 63
     65 2018-04-25 15:12:14,679  INFO [Thread-61] (EmployeeService.java:36) - oldMoney: 64
     66 2018-04-25 15:12:14,680  INFO [Thread-58] (EmployeeService.java:36) - oldMoney: 65
     67 2018-04-25 15:12:14,681  INFO [Thread-80] (EmployeeService.java:36) - oldMoney: 66
     68 2018-04-25 15:12:14,682  INFO [Thread-76] (EmployeeService.java:36) - oldMoney: 67
     69 2018-04-25 15:12:14,684  INFO [Thread-78] (EmployeeService.java:36) - oldMoney: 68
     70 2018-04-25 15:12:14,685  INFO [Thread-100] (EmployeeService.java:36) - oldMoney: 69
     71 2018-04-25 15:12:14,686  INFO [Thread-99] (EmployeeService.java:36) - oldMoney: 70
     72 2018-04-25 15:12:14,688  INFO [Thread-79] (EmployeeService.java:36) - oldMoney: 71
     73 2018-04-25 15:12:14,689  INFO [Thread-94] (EmployeeService.java:36) - oldMoney: 72
     74 2018-04-25 15:12:14,690  INFO [Thread-60] (EmployeeService.java:36) - oldMoney: 73
     75 2018-04-25 15:12:14,691  INFO [Thread-77] (EmployeeService.java:36) - oldMoney: 74
     76 2018-04-25 15:12:14,709  INFO [Thread-95] (EmployeeService.java:36) - oldMoney: 75
     77 2018-04-25 15:12:14,711  INFO [Thread-96] (EmployeeService.java:36) - oldMoney: 76
     78 2018-04-25 15:12:14,712  INFO [Thread-98] (EmployeeService.java:36) - oldMoney: 77
     79 2018-04-25 15:12:14,738  INFO [Thread-75] (EmployeeService.java:36) - oldMoney: 78
     80 2018-04-25 15:12:14,740  INFO [Thread-74] (EmployeeService.java:36) - oldMoney: 79
     81 2018-04-25 15:12:14,741  INFO [Thread-73] (EmployeeService.java:36) - oldMoney: 80
     82 2018-04-25 15:12:14,742  INFO [Thread-71] (EmployeeService.java:36) - oldMoney: 81
     83 2018-04-25 15:12:14,743  INFO [Thread-69] (EmployeeService.java:36) - oldMoney: 82
     84 2018-04-25 15:12:14,745  INFO [Thread-70] (EmployeeService.java:36) - oldMoney: 83
     85 2018-04-25 15:12:14,746  INFO [Thread-68] (EmployeeService.java:36) - oldMoney: 84
     86 2018-04-25 15:12:14,748  INFO [Thread-66] (EmployeeService.java:36) - oldMoney: 85
     87 2018-04-25 15:12:14,749  INFO [Thread-67] (EmployeeService.java:36) - oldMoney: 86
     88 2018-04-25 15:12:14,751  INFO [Thread-64] (EmployeeService.java:36) - oldMoney: 87
     89 2018-04-25 15:12:14,754  INFO [Thread-65] (EmployeeService.java:36) - oldMoney: 88
     90 2018-04-25 15:12:14,755  INFO [Thread-63] (EmployeeService.java:36) - oldMoney: 89
     91 2018-04-25 15:12:14,767  INFO [Thread-97] (EmployeeService.java:36) - oldMoney: 90
     92 2018-04-25 15:12:14,769  INFO [Thread-93] (EmployeeService.java:36) - oldMoney: 91
     93 2018-04-25 15:12:14,770  INFO [Thread-49] (EmployeeService.java:36) - oldMoney: 92
     94 2018-04-25 15:12:14,796  INFO [Thread-92] (EmployeeService.java:36) - oldMoney: 93
     95 2018-04-25 15:12:14,801  INFO [Thread-91] (EmployeeService.java:36) - oldMoney: 94
     96 2018-04-25 15:12:14,803  INFO [Thread-89] (EmployeeService.java:36) - oldMoney: 95
     97 2018-04-25 15:12:14,803  INFO [Thread-90] (EmployeeService.java:36) - oldMoney: 96
     98 2018-04-25 15:12:14,804  INFO [Thread-88] (EmployeeService.java:36) - oldMoney: 97
     99 2018-04-25 15:12:14,806  INFO [Thread-87] (EmployeeService.java:36) - oldMoney: 98
    100 2018-04-25 15:12:14,807  INFO [Thread-86] (EmployeeService.java:36) - oldMoney: 99
    

      

    可以看到,oldMoney 值由0到99依次严格递增且不重复(这就是想要的效果)。

    第二部分 乐观锁

    1 概念

    1.1 理解方式一(来自网上其它小伙伴的博客)

    乐观锁认为一般情况下数据不会造成冲突,所以在数据进行提交更新时才会对数据的冲突与否进行检测。如果没有冲突那就OK;如果出现冲突了,则返回错误信息并让用户决定如何去做。

    1.2 理解方式二(来自网上其它小伙伴的博客)

    乐观锁的特点是先进行业务操作,不到万不得已不会去拿锁。乐观地认为拿锁多半会是成功的,因此在完成业务操作需要实际更新数据的最后一步再去拿一下锁。

    1.3 我的理解

    理解一:就是 CAS 操作

    理解二:类似于 SVN、GIt 这些版本管理系统,当修改了某个文件需要提交的时候,它会检查文件的当前版本是否与服务器上的一致,如果一致那就可以直接提交,如果不一致,那就必须先更新服务器上的最新代码然后再提交(也就是先将这个文件的版本更新成和服务器一样的版本)

    2 如何实现乐观锁呢

    首先说明一点的是:乐观锁在数据库上的实现完全是逻辑的,数据库本身不提供支持,而是需要开发者自己来实现。

    常见的做法有两种:版本号控制及时间戳控制。

    版本号控制的原理:

    • 为表中加一个 version 字段;
    • 当读取数据时,连同这个 version 字段一起读出;
    • 数据每更新一次就将此值加一;
    • 当提交更新时,判断数据库表中对应记录的当前版本号是否与之前取出来的版本号一致,如果一致则可以直接更新,如果不一致则表示是过期数据需要重试或者做其它操作(PS:这完完全全就是 CAS 的实现逻辑呀~)

    至于时间戳控制,其原理和版本号控制差不多,也是在表中添加一个 timestamp 的时间戳字段,然后提交更新时判断数据库中对应记录的当前时间戳是否与之前取出来的时间戳一致,一致就更新,不一致就重试。

    3 Java代码演示

    3.1 准备

    还是之前的Java代码;这里使用版本号控制来实现乐观锁。

    3.2 业务逻辑代码

    XMP 文件中的 Mapper:

        <update id="updateEmployeeWithOptimisticLock">
            UPDATE employee SET money = #{e.money}, version = #{e.version} + 1 WHERE id = #{e.id} AND #{e.version} = version
        </update>

    提示:

    • SET 中有 version = #{e.version} + 1 的操作
    • WHERE 条件中有 #{e.version} = version 的判断

    Service 中的业务逻辑:

    复制代码
     1     /**
     2      * 失败尝试
     3      * @param id
     4      */
     5     public void increaseMoneyWithOptimisticLock(Integer id) {
     6         int tryTimes = 0;
     7         while (true) {
     8             tryTimes++;
     9             if (internalIncreaseMoneyWithOptimisticLock(id) != 0) {
    10                 // 说明更新成功,直接退出
    11                 break;
    12             }
    13             if (tryTimes == 200) {
    14                 // 达到最大重试次数,退出
    15                 break;
    16             }
    17             try {
    18                 // 休息一段时间后再重试
    19                 TimeUnit.MILLISECONDS.sleep(new Random().nextInt(1000));
    20             } catch (InterruptedException e) {
    21                 e.printStackTrace();
    22                 Thread.currentThread().interrupt();
    23             }
    24         }
    25         LOGGER.info("tryTimes: {}", tryTimes);
    26     }
    27 
    28     /**
    29      * 查找Employee对象,并进行更新
    30      * @param id
    31      * @return
    32      */
    33     @Transactional(rollbackFor = RuntimeException.class)
    34     public Integer internalIncreaseMoneyWithOptimisticLock(Integer id) {
    35         Employee employee = employeeMapper.findById(id);
    36         final Integer oldMoney = employee.getMoney();
    37         LOGGER.info("oldMoney: {}", oldMoney);
    38         employee.setMoney(oldMoney + 1);
    39         return employeeMapper.updateEmployeeWithOptimisticLock(employee);
    40     }
    复制代码

    提示:

    • 乐观锁,其实是开发者自己实现的逻辑
    • 更新失败后,休息一段时间后再进行重试

    3.3 测试代码

        private void increaseMoneyWithOptimisticLock() {
            int threadCount = 100;
            while (threadCount-- > 0) {
                new Thread(() -> employeeService.increaseMoneyWithOptimisticLock(1)).start();
            }
        }

    提示:100根线程,每个线程将Money值加1,预期结果是Money的值在之前的基础上增加100

    3.4 执行测试&查看结果

    之前Money=100,现在预期增加100,所以现在Money=200符合预期。同时,version 字段的值也由最初的1更新为101(也被更新了100次,每次加一)。

    3.5 查看日志

    1 2018-04-25 16:24:07,851  INFO [Thread-36] (EmployeeService.java:77) - oldMoney: 100
      2 2018-04-25 16:24:07,853  INFO [Thread-54] (EmployeeService.java:77) - oldMoney: 100
      3 2018-04-25 16:24:07,856  INFO [Thread-55] (EmployeeService.java:77) - oldMoney: 100
      4 2018-04-25 16:24:07,856  INFO [Thread-45] (EmployeeService.java:77) - oldMoney: 100
      5 2018-04-25 16:24:07,858  INFO [Thread-56] (EmployeeService.java:77) - oldMoney: 100
      6 2018-04-25 16:24:07,858  INFO [Thread-53] (EmployeeService.java:77) - oldMoney: 100
      7 2018-04-25 16:24:07,858  INFO [Thread-33] (EmployeeService.java:77) - oldMoney: 100
      8 2018-04-25 16:24:07,859  INFO [Thread-57] (EmployeeService.java:77) - oldMoney: 100
      9 2018-04-25 16:24:07,859  INFO [Thread-31] (EmployeeService.java:77) - oldMoney: 100
     10 2018-04-25 16:24:07,863  INFO [Thread-30] (EmployeeService.java:77) - oldMoney: 101
     11 2018-04-25 16:24:07,868  INFO [Thread-29] (EmployeeService.java:77) - oldMoney: 101
     12 2018-04-25 16:24:07,880  INFO [Thread-75] (EmployeeService.java:77) - oldMoney: 101
     13 2018-04-25 16:24:07,881  INFO [Thread-76] (EmployeeService.java:77) - oldMoney: 102
     14 2018-04-25 16:24:07,882  INFO [Thread-78] (EmployeeService.java:77) - oldMoney: 102
     15 2018-04-25 16:24:07,883  INFO [Thread-77] (EmployeeService.java:77) - oldMoney: 102
     16 2018-04-25 16:24:07,885  INFO [Thread-79] (EmployeeService.java:77) - oldMoney: 103
     17 2018-04-25 16:24:07,887  INFO [Thread-80] (EmployeeService.java:77) - oldMoney: 103
     18 2018-04-25 16:24:07,888  INFO [Thread-28] (EmployeeService.java:77) - oldMoney: 104
     19 2018-04-25 16:24:07,890  INFO [Thread-27] (EmployeeService.java:77) - oldMoney: 104
     20 2018-04-25 16:24:07,892  INFO [Thread-26] (EmployeeService.java:77) - oldMoney: 105
     21 2018-04-25 16:24:07,894  INFO [Thread-25] (EmployeeService.java:77) - oldMoney: 105
     22 2018-04-25 16:24:07,895  INFO [Thread-24] (EmployeeService.java:77) - oldMoney: 106
     23 2018-04-25 16:24:07,897  INFO [Thread-83] (EmployeeService.java:77) - oldMoney: 106
     24 2018-04-25 16:24:07,898  INFO [Thread-82] (EmployeeService.java:77) - oldMoney: 106
     25 2018-04-25 16:24:07,900  INFO [Thread-84] (EmployeeService.java:77) - oldMoney: 107
     26 2018-04-25 16:24:07,904  INFO [Thread-21] (EmployeeService.java:77) - oldMoney: 108
     27 2018-04-25 16:24:07,906  INFO [Thread-20] (EmployeeService.java:77) - oldMoney: 109
     28 2018-04-25 16:24:07,907  INFO [Thread-6] (EmployeeService.java:77) - oldMoney: 109
     29 2018-04-25 16:24:07,908  INFO [Thread-9] (EmployeeService.java:77) - oldMoney: 110
     30 2018-04-25 16:24:07,909  INFO [Thread-85] (EmployeeService.java:77) - oldMoney: 110
     31 2018-04-25 16:24:07,909  INFO [Thread-86] (EmployeeService.java:77) - oldMoney: 111
     32 2018-04-25 16:24:07,911  INFO [Thread-91] (EmployeeService.java:77) - oldMoney: 111
     33 2018-04-25 16:24:07,912  INFO [Thread-81] (EmployeeService.java:77) - oldMoney: 112
     34 2018-04-25 16:24:07,913  INFO [Thread-90] (EmployeeService.java:77) - oldMoney: 112
     35 2018-04-25 16:24:07,915  INFO [Thread-96] (EmployeeService.java:77) - oldMoney: 112
     36 2018-04-25 16:24:07,924  INFO [Thread-97] (EmployeeService.java:77) - oldMoney: 113
     37 2018-04-25 16:24:07,926  INFO [Thread-36] (EmployeeService.java:65) - tryTimes: 1
     38 2018-04-25 16:24:07,928  INFO [Thread-18] (EmployeeService.java:77) - oldMoney: 113
     39 2018-04-25 16:24:07,929  INFO [Thread-4] (EmployeeService.java:77) - oldMoney: 113
     40 2018-04-25 16:24:07,932  INFO [Thread-94] (EmployeeService.java:77) - oldMoney: 114
     41 2018-04-25 16:24:07,934  INFO [Thread-12] (EmployeeService.java:77) - oldMoney: 114
     42 2018-04-25 16:24:07,935  INFO [Thread-93] (EmployeeService.java:77) - oldMoney: 114
     43 2018-04-25 16:24:07,939  INFO [Thread-92] (EmployeeService.java:77) - oldMoney: 115
     44 2018-04-25 16:24:07,940  INFO [Thread-69] (EmployeeService.java:77) - oldMoney: 115
     45 2018-04-25 16:24:07,960  INFO [Thread-86] (EmployeeService.java:65) - tryTimes: 1
     46 2018-04-25 16:24:07,961  INFO [Thread-9] (EmployeeService.java:65) - tryTimes: 1
     47 2018-04-25 16:24:07,960  INFO [Thread-75] (EmployeeService.java:65) - tryTimes: 1
     48 2018-04-25 16:24:07,962  INFO [Thread-33] (EmployeeService.java:77) - oldMoney: 116
     49 2018-04-25 16:24:07,963  INFO [Thread-87] (EmployeeService.java:77) - oldMoney: 116
     50 2018-04-25 16:24:07,963  INFO [Thread-6] (EmployeeService.java:77) - oldMoney: 116
     51 2018-04-25 16:24:07,964  INFO [Thread-20] (EmployeeService.java:65) - tryTimes: 1
     52 2018-04-25 16:24:07,964  INFO [Thread-21] (EmployeeService.java:65) - tryTimes: 1
     53 2018-04-25 16:24:07,964  INFO [Thread-90] (EmployeeService.java:65) - tryTimes: 1
     54 2018-04-25 16:24:07,965  INFO [Thread-26] (EmployeeService.java:65) - tryTimes: 1
     55 2018-04-25 16:24:07,965  INFO [Thread-28] (EmployeeService.java:65) - tryTimes: 1
     56 2018-04-25 16:24:07,965  INFO [Thread-83] (EmployeeService.java:65) - tryTimes: 1
     57 2018-04-25 16:24:07,966  INFO [Thread-76] (EmployeeService.java:65) - tryTimes: 1
     58 2018-04-25 16:24:07,966  INFO [Thread-79] (EmployeeService.java:65) - tryTimes: 1
     59 2018-04-25 16:24:07,967  INFO [Thread-84] (EmployeeService.java:65) - tryTimes: 1
     60 2018-04-25 16:24:07,974  INFO [Thread-16] (EmployeeService.java:77) - oldMoney: 116
     61 2018-04-25 16:24:07,974  INFO [Thread-17] (EmployeeService.java:77) - oldMoney: 116
     62 2018-04-25 16:24:07,974  INFO [Thread-89] (EmployeeService.java:77) - oldMoney: 116
     63 2018-04-25 16:24:07,975  INFO [Thread-13] (EmployeeService.java:77) - oldMoney: 116
     64 2018-04-25 16:24:07,976  INFO [Thread-7] (EmployeeService.java:77) - oldMoney: 116
     65 2018-04-25 16:24:07,976  INFO [Thread-100] (EmployeeService.java:77) - oldMoney: 116
     66 2018-04-25 16:24:07,976  INFO [Thread-95] (EmployeeService.java:77) - oldMoney: 116
     67 2018-04-25 16:24:07,978  INFO [Thread-88] (EmployeeService.java:77) - oldMoney: 116
     68 2018-04-25 16:24:07,978  INFO [Thread-8] (EmployeeService.java:77) - oldMoney: 117
     69 2018-04-25 16:24:07,979  INFO [Thread-11] (EmployeeService.java:77) - oldMoney: 117
     70 2018-04-25 16:24:07,980  INFO [Thread-5] (EmployeeService.java:77) - oldMoney: 118
     71 2018-04-25 16:24:07,980  INFO [Thread-19] (EmployeeService.java:77) - oldMoney: 118
     72 2018-04-25 16:24:07,980  INFO [Thread-22] (EmployeeService.java:77) - oldMoney: 118
     73 2018-04-25 16:24:07,981  INFO [Thread-2] (EmployeeService.java:77) - oldMoney: 119
     74 2018-04-25 16:24:07,981  INFO [Thread-23] (EmployeeService.java:77) - oldMoney: 119
     75 2018-04-25 16:24:07,982  INFO [Thread-35] (EmployeeService.java:77) - oldMoney: 119
     76 2018-04-25 16:24:07,982  INFO [Thread-32] (EmployeeService.java:77) - oldMoney: 119
     77 2018-04-25 16:24:07,983  INFO [Thread-34] (EmployeeService.java:77) - oldMoney: 120
     78 2018-04-25 16:24:07,983  INFO [Thread-37] (EmployeeService.java:77) - oldMoney: 120
     79 2018-04-25 16:24:07,984  INFO [Thread-38] (EmployeeService.java:77) - oldMoney: 120
     80 2018-04-25 16:24:07,985  INFO [Thread-39] (EmployeeService.java:77) - oldMoney: 121
     81 2018-04-25 16:24:07,985  INFO [Thread-40] (EmployeeService.java:77) - oldMoney: 121
     82 2018-04-25 16:24:07,986  INFO [Thread-41] (EmployeeService.java:77) - oldMoney: 121
     83 2018-04-25 16:24:07,986  INFO [Thread-43] (EmployeeService.java:77) - oldMoney: 121
     84 2018-04-25 16:24:07,987  INFO [Thread-44] (EmployeeService.java:77) - oldMoney: 122
     85 2018-04-25 16:24:07,988  INFO [Thread-48] (EmployeeService.java:77) - oldMoney: 122
     86 2018-04-25 16:24:07,988  INFO [Thread-49] (EmployeeService.java:77) - oldMoney: 122
     87 2018-04-25 16:24:07,989  INFO [Thread-50] (EmployeeService.java:77) - oldMoney: 122
     88 2018-04-25 16:24:07,986  INFO [Thread-42] (EmployeeService.java:77) - oldMoney: 121
     89 2018-04-25 16:24:07,990  INFO [Thread-52] (EmployeeService.java:77) - oldMoney: 123
     90 2018-04-25 16:24:07,989  INFO [Thread-51] (EmployeeService.java:77) - oldMoney: 122
     91 2018-04-25 16:24:07,988  INFO [Thread-47] (EmployeeService.java:77) - oldMoney: 122
     92 2018-04-25 16:24:07,987  INFO [Thread-46] (EmployeeService.java:77) - oldMoney: 122
     93 2018-04-25 16:24:07,991  INFO [Thread-60] (EmployeeService.java:77) - oldMoney: 123
     94 2018-04-25 16:24:07,990  INFO [Thread-58] (EmployeeService.java:77) - oldMoney: 123
     95 2018-04-25 16:24:07,992  INFO [Thread-64] (EmployeeService.java:77) - oldMoney: 124
     96 2018-04-25 16:24:07,992  INFO [Thread-65] (EmployeeService.java:77) - oldMoney: 124
     97 2018-04-25 16:24:07,992  INFO [Thread-61] (EmployeeService.java:77) - oldMoney: 124
     98 2018-04-25 16:24:07,993  INFO [Thread-63] (EmployeeService.java:77) - oldMoney: 125
     99 2018-04-25 16:24:07,995  INFO [Thread-68] (EmployeeService.java:77) - oldMoney: 125
    100 2018-04-25 16:24:07,995  INFO [Thread-67] (EmployeeService.java:77) - oldMoney: 125
    101 2018-04-25 16:24:07,995  INFO [Thread-15] (EmployeeService.java:77) - oldMoney: 125
    102 2018-04-25 16:24:07,996  INFO [Thread-66] (EmployeeService.java:77) - oldMoney: 125
    103 2018-04-25 16:24:07,997  INFO [Thread-99] (EmployeeService.java:77) - oldMoney: 126
    104 2018-04-25 16:24:07,998  INFO [Thread-98] (EmployeeService.java:77) - oldMoney: 126
    105 2018-04-25 16:24:07,998  INFO [Thread-74] (EmployeeService.java:77) - oldMoney: 126
    106 2018-04-25 16:24:08,002  INFO [Thread-92] (EmployeeService.java:65) - tryTimes: 1
    107 2018-04-25 16:24:08,002  INFO [Thread-73] (EmployeeService.java:77) - oldMoney: 127
    108 2018-04-25 16:24:08,002  INFO [Thread-18] (EmployeeService.java:65) - tryTimes: 1
    109 2018-04-25 16:24:08,004  INFO [Thread-62] (EmployeeService.java:77) - oldMoney: 127
    110 2018-04-25 16:24:08,004  INFO [Thread-27] (EmployeeService.java:77) - oldMoney: 127
    111 2018-04-25 16:24:08,005  INFO [Thread-46] (EmployeeService.java:77) - oldMoney: 128
    112 2018-04-25 16:24:08,006  INFO [Thread-59] (EmployeeService.java:77) - oldMoney: 128
    113 2018-04-25 16:24:08,006  INFO [Thread-71] (EmployeeService.java:77) - oldMoney: 128
    114 2018-04-25 16:24:08,006  INFO [Thread-3] (EmployeeService.java:77) - oldMoney: 128
    115 2018-04-25 16:24:08,007  INFO [Thread-56] (EmployeeService.java:77) - oldMoney: 128
    116 2018-04-25 16:24:08,008  INFO [Thread-72] (EmployeeService.java:77) - oldMoney: 128
    117 2018-04-25 16:24:08,008  INFO [Thread-93] (EmployeeService.java:65) - tryTimes: 1
    118 2018-04-25 16:24:08,010  INFO [Thread-70] (EmployeeService.java:77) - oldMoney: 129
    119 2018-04-25 16:24:08,010  INFO [Thread-10] (EmployeeService.java:77) - oldMoney: 129
    120 2018-04-25 16:24:08,010  INFO [Thread-17] (EmployeeService.java:77) - oldMoney: 129
    121 2018-04-25 16:24:08,011  INFO [Thread-14] (EmployeeService.java:77) - oldMoney: 129
    122 2018-04-25 16:24:08,012  INFO [Thread-1] (EmployeeService.java:77) - oldMoney: 130
    123 2018-04-25 16:24:08,032  INFO [Thread-5] (EmployeeService.java:65) - tryTimes: 1
    124 2018-04-25 16:24:08,032  INFO [Thread-49] (EmployeeService.java:65) - tryTimes: 1
    125 2018-04-25 16:24:08,032  INFO [Thread-87] (EmployeeService.java:65) - tryTimes: 1
    126 2018-04-25 16:24:08,032  INFO [Thread-64] (EmployeeService.java:65) - tryTimes: 1
    127 2018-04-25 16:24:08,032  INFO [Thread-8] (EmployeeService.java:65) - tryTimes: 1
    128 2018-04-25 16:24:08,033  INFO [Thread-41] (EmployeeService.java:65) - tryTimes: 1
    129 2018-04-25 16:24:08,033  INFO [Thread-52] (EmployeeService.java:65) - tryTimes: 1
    130 2018-04-25 16:24:08,034  INFO [Thread-2] (EmployeeService.java:65) - tryTimes: 1
    131 2018-04-25 16:24:08,034  INFO [Thread-72] (EmployeeService.java:77) - oldMoney: 131
    132 2018-04-25 16:24:08,035  INFO [Thread-99] (EmployeeService.java:65) - tryTimes: 1
    133 2018-04-25 16:24:08,035  INFO [Thread-34] (EmployeeService.java:65) - tryTimes: 1
    134 2018-04-25 16:24:08,035  INFO [Thread-68] (EmployeeService.java:65) - tryTimes: 1
    135 2018-04-25 16:24:08,037  INFO [Thread-30] (EmployeeService.java:77) - oldMoney: 131
    136 2018-04-25 16:24:08,049  INFO [Thread-30] (EmployeeService.java:77) - oldMoney: 132
    137 2018-04-25 16:24:08,068  INFO [Thread-3] (EmployeeService.java:65) - tryTimes: 1
    138 2018-04-25 16:24:08,068  INFO [Thread-10] (EmployeeService.java:65) - tryTimes: 1
    139 2018-04-25 16:24:08,068  INFO [Thread-73] (EmployeeService.java:65) - tryTimes: 1
    140 2018-04-25 16:24:08,068  INFO [Thread-1] (EmployeeService.java:65) - tryTimes: 1
    141 2018-04-25 16:24:08,070  INFO [Thread-24] (EmployeeService.java:77) - oldMoney: 133
    142 2018-04-25 16:24:08,082  INFO [Thread-69] (EmployeeService.java:77) - oldMoney: 134
    143 2018-04-25 16:24:08,087  INFO [Thread-60] (EmployeeService.java:77) - oldMoney: 135
    144 2018-04-25 16:24:08,117  INFO [Thread-38] (EmployeeService.java:77) - oldMoney: 136
    145 2018-04-25 16:24:08,125  INFO [Thread-46] (EmployeeService.java:77) - oldMoney: 137
    146 2018-04-25 16:24:08,131  INFO [Thread-30] (EmployeeService.java:65) - tryTimes: 3
    147 2018-04-25 16:24:08,132  INFO [Thread-72] (EmployeeService.java:65) - tryTimes: 2
    148 2018-04-25 16:24:08,149  INFO [Thread-11] (EmployeeService.java:77) - oldMoney: 138
    149 2018-04-25 16:24:08,170  INFO [Thread-98] (EmployeeService.java:77) - oldMoney: 139
    150 2018-04-25 16:24:08,180  INFO [Thread-60] (EmployeeService.java:65) - tryTimes: 2
    151 2018-04-25 16:24:08,181  INFO [Thread-46] (EmployeeService.java:65) - tryTimes: 3
    152 2018-04-25 16:24:08,180  INFO [Thread-69] (EmployeeService.java:65) - tryTimes: 2
    153 2018-04-25 16:24:08,180  INFO [Thread-38] (EmployeeService.java:65) - tryTimes: 2
    154 2018-04-25 16:24:08,180  INFO [Thread-24] (EmployeeService.java:65) - tryTimes: 2
    155 2018-04-25 16:24:08,188  INFO [Thread-71] (EmployeeService.java:77) - oldMoney: 140
    156 2018-04-25 16:24:08,204  INFO [Thread-96] (EmployeeService.java:77) - oldMoney: 141
    157 2018-04-25 16:24:08,210  INFO [Thread-11] (EmployeeService.java:65) - tryTimes: 2
    158 2018-04-25 16:24:08,210  INFO [Thread-98] (EmployeeService.java:65) - tryTimes: 2
    159 2018-04-25 16:24:08,230  INFO [Thread-91] (EmployeeService.java:77) - oldMoney: 142
    160 2018-04-25 16:24:08,239  INFO [Thread-71] (EmployeeService.java:65) - tryTimes: 2
    161 2018-04-25 16:24:08,239  INFO [Thread-96] (EmployeeService.java:65) - tryTimes: 2
    162 2018-04-25 16:24:08,254  INFO [Thread-25] (EmployeeService.java:77) - oldMoney: 143
    163 2018-04-25 16:24:08,254  INFO [Thread-58] (EmployeeService.java:77) - oldMoney: 143
    164 2018-04-25 16:24:08,263  INFO [Thread-17] (EmployeeService.java:77) - oldMoney: 144
    165 2018-04-25 16:24:08,268  INFO [Thread-91] (EmployeeService.java:65) - tryTimes: 2
    166 2018-04-25 16:24:08,275  INFO [Thread-63] (EmployeeService.java:77) - oldMoney: 145
    167 2018-04-25 16:24:08,275  INFO [Thread-89] (EmployeeService.java:77) - oldMoney: 145
    168 2018-04-25 16:24:08,277  INFO [Thread-51] (EmployeeService.java:77) - oldMoney: 146
    169 2018-04-25 16:24:08,279  INFO [Thread-56] (EmployeeService.java:77) - oldMoney: 147
    170 2018-04-25 16:24:08,280  INFO [Thread-40] (EmployeeService.java:77) - oldMoney: 147
    171 2018-04-25 16:24:08,280  INFO [Thread-65] (EmployeeService.java:77) - oldMoney: 147
    172 2018-04-25 16:24:08,287  INFO [Thread-100] (EmployeeService.java:77) - oldMoney: 148
    173 2018-04-25 16:24:08,298  INFO [Thread-25] (EmployeeService.java:65) - tryTimes: 2
    174 2018-04-25 16:24:08,299  INFO [Thread-17] (EmployeeService.java:65) - tryTimes: 3
    175 2018-04-25 16:24:08,310  INFO [Thread-47] (EmployeeService.java:77) - oldMoney: 149
    176 2018-04-25 16:24:08,319  INFO [Thread-6] (EmployeeService.java:77) - oldMoney: 150
    177 2018-04-25 16:24:08,327  INFO [Thread-100] (EmployeeService.java:65) - tryTimes: 2
    178 2018-04-25 16:24:08,327  INFO [Thread-56] (EmployeeService.java:65) - tryTimes: 3
    179 2018-04-25 16:24:08,327  INFO [Thread-63] (EmployeeService.java:65) - tryTimes: 2
    180 2018-04-25 16:24:08,328  INFO [Thread-51] (EmployeeService.java:65) - tryTimes: 2
    181 2018-04-25 16:24:08,364  INFO [Thread-6] (EmployeeService.java:65) - tryTimes: 3
    182 2018-04-25 16:24:08,365  INFO [Thread-47] (EmployeeService.java:65) - tryTimes: 2
    183 2018-04-25 16:24:08,388  INFO [Thread-33] (EmployeeService.java:77) - oldMoney: 151
    184 2018-04-25 16:24:08,400  INFO [Thread-58] (EmployeeService.java:77) - oldMoney: 152
    185 2018-04-25 16:24:08,404  INFO [Thread-35] (EmployeeService.java:77) - oldMoney: 153
    186 2018-04-25 16:24:08,424  INFO [Thread-89] (EmployeeService.java:77) - oldMoney: 154
    187 2018-04-25 16:24:08,427  INFO [Thread-33] (EmployeeService.java:65) - tryTimes: 3
    188 2018-04-25 16:24:08,431  INFO [Thread-88] (EmployeeService.java:77) - oldMoney: 155
    189 2018-04-25 16:24:08,453  INFO [Thread-12] (EmployeeService.java:77) - oldMoney: 156
    190 2018-04-25 16:24:08,454  INFO [Thread-70] (EmployeeService.java:77) - oldMoney: 157
    191 2018-04-25 16:24:08,457  INFO [Thread-89] (EmployeeService.java:65) - tryTimes: 3
    192 2018-04-25 16:24:08,457  INFO [Thread-58] (EmployeeService.java:65) - tryTimes: 3
    193 2018-04-25 16:24:08,458  INFO [Thread-35] (EmployeeService.java:65) - tryTimes: 2
    194 2018-04-25 16:24:08,459  INFO [Thread-54] (EmployeeService.java:77) - oldMoney: 158
    195 2018-04-25 16:24:08,461  INFO [Thread-67] (EmployeeService.java:77) - oldMoney: 159
    196 2018-04-25 16:24:08,470  INFO [Thread-31] (EmployeeService.java:77) - oldMoney: 160
    197 2018-04-25 16:24:08,485  INFO [Thread-12] (EmployeeService.java:65) - tryTimes: 2
    198 2018-04-25 16:24:08,485  INFO [Thread-70] (EmployeeService.java:65) - tryTimes: 2
    199 2018-04-25 16:24:08,486  INFO [Thread-88] (EmployeeService.java:65) - tryTimes: 2
    200 2018-04-25 16:24:08,488  INFO [Thread-81] (EmployeeService.java:77) - oldMoney: 161
    201 2018-04-25 16:24:08,497  INFO [Thread-23] (EmployeeService.java:77) - oldMoney: 162
    202 2018-04-25 16:24:08,504  INFO [Thread-82] (EmployeeService.java:77) - oldMoney: 163
    203 2018-04-25 16:24:08,507  INFO [Thread-50] (EmployeeService.java:77) - oldMoney: 164
    204 2018-04-25 16:24:08,510  INFO [Thread-78] (EmployeeService.java:77) - oldMoney: 165
    205 2018-04-25 16:24:08,514  INFO [Thread-67] (EmployeeService.java:65) - tryTimes: 2
    206 2018-04-25 16:24:08,514  INFO [Thread-54] (EmployeeService.java:65) - tryTimes: 2
    207 2018-04-25 16:24:08,516  INFO [Thread-97] (EmployeeService.java:77) - oldMoney: 166
    208 2018-04-25 16:24:08,517  INFO [Thread-31] (EmployeeService.java:65) - tryTimes: 2
    209 2018-04-25 16:24:08,534  INFO [Thread-61] (EmployeeService.java:77) - oldMoney: 167
    210 2018-04-25 16:24:08,538  INFO [Thread-29] (EmployeeService.java:77) - oldMoney: 168
    211 2018-04-25 16:24:08,543  INFO [Thread-23] (EmployeeService.java:65) - tryTimes: 2
    212 2018-04-25 16:24:08,544  INFO [Thread-81] (EmployeeService.java:65) - tryTimes: 2
    213 2018-04-25 16:24:08,544  INFO [Thread-50] (EmployeeService.java:65) - tryTimes: 2
    214 2018-04-25 16:24:08,543  INFO [Thread-82] (EmployeeService.java:65) - tryTimes: 2
    215 2018-04-25 16:24:08,544  INFO [Thread-78] (EmployeeService.java:65) - tryTimes: 2
    216 2018-04-25 16:24:08,556  INFO [Thread-74] (EmployeeService.java:77) - oldMoney: 169
    217 2018-04-25 16:24:08,572  INFO [Thread-61] (EmployeeService.java:65) - tryTimes: 2
    218 2018-04-25 16:24:08,573  INFO [Thread-29] (EmployeeService.java:65) - tryTimes: 2
    219 2018-04-25 16:24:08,572  INFO [Thread-97] (EmployeeService.java:65) - tryTimes: 2
    220 2018-04-25 16:24:08,582  INFO [Thread-80] (EmployeeService.java:77) - oldMoney: 170
    221 2018-04-25 16:24:08,583  INFO [Thread-48] (EmployeeService.java:77) - oldMoney: 171
    222 2018-04-25 16:24:08,584  INFO [Thread-27] (EmployeeService.java:77) - oldMoney: 172
    223 2018-04-25 16:24:08,589  INFO [Thread-32] (EmployeeService.java:77) - oldMoney: 173
    224 2018-04-25 16:24:08,602  INFO [Thread-74] (EmployeeService.java:65) - tryTimes: 2
    225 2018-04-25 16:24:08,608  INFO [Thread-85] (EmployeeService.java:77) - oldMoney: 174
    226 2018-04-25 16:24:08,631  INFO [Thread-32] (EmployeeService.java:65) - tryTimes: 2
    227 2018-04-25 16:24:08,631  INFO [Thread-27] (EmployeeService.java:65) - tryTimes: 3
    228 2018-04-25 16:24:08,631  INFO [Thread-80] (EmployeeService.java:65) - tryTimes: 2
    229 2018-04-25 16:24:08,632  INFO [Thread-48] (EmployeeService.java:65) - tryTimes: 2
    230 2018-04-25 16:24:08,634  INFO [Thread-22] (EmployeeService.java:77) - oldMoney: 175
    231 2018-04-25 16:24:08,660  INFO [Thread-85] (EmployeeService.java:65) - tryTimes: 2
    232 2018-04-25 16:24:08,689  INFO [Thread-22] (EmployeeService.java:65) - tryTimes: 2
    233 2018-04-25 16:24:08,696  INFO [Thread-44] (EmployeeService.java:77) - oldMoney: 176
    234 2018-04-25 16:24:08,696  INFO [Thread-43] (EmployeeService.java:77) - oldMoney: 176
    235 2018-04-25 16:24:08,704  INFO [Thread-13] (EmployeeService.java:77) - oldMoney: 177
    236 2018-04-25 16:24:08,712  INFO [Thread-4] (EmployeeService.java:77) - oldMoney: 178
    237 2018-04-25 16:24:08,722  INFO [Thread-45] (EmployeeService.java:77) - oldMoney: 179
    238 2018-04-25 16:24:08,723  INFO [Thread-7] (EmployeeService.java:77) - oldMoney: 179
    239 2018-04-25 16:24:08,727  INFO [Thread-44] (EmployeeService.java:65) - tryTimes: 2
    240 2018-04-25 16:24:08,743  INFO [Thread-77] (EmployeeService.java:77) - oldMoney: 180
    241 2018-04-25 16:24:08,748  INFO [Thread-59] (EmployeeService.java:77) - oldMoney: 181
    242 2018-04-25 16:24:08,754  INFO [Thread-57] (EmployeeService.java:77) - oldMoney: 182
    243 2018-04-25 16:24:08,756  INFO [Thread-45] (EmployeeService.java:65) - tryTimes: 2
    244 2018-04-25 16:24:08,756  INFO [Thread-13] (EmployeeService.java:65) - tryTimes: 2
    245 2018-04-25 16:24:08,757  INFO [Thread-4] (EmployeeService.java:65) - tryTimes: 2
    246 2018-04-25 16:24:08,765  INFO [Thread-39] (EmployeeService.java:77) - oldMoney: 183
    247 2018-04-25 16:24:08,779  INFO [Thread-66] (EmployeeService.java:77) - oldMoney: 184
    248 2018-04-25 16:24:08,785  INFO [Thread-59] (EmployeeService.java:65) - tryTimes: 2
    249 2018-04-25 16:24:08,785  INFO [Thread-77] (EmployeeService.java:65) - tryTimes: 2
    250 2018-04-25 16:24:08,796  INFO [Thread-55] (EmployeeService.java:77) - oldMoney: 185
    251 2018-04-25 16:24:08,811  INFO [Thread-62] (EmployeeService.java:77) - oldMoney: 186
    252 2018-04-25 16:24:08,814  INFO [Thread-39] (EmployeeService.java:65) - tryTimes: 2
    253 2018-04-25 16:24:08,814  INFO [Thread-57] (EmployeeService.java:65) - tryTimes: 2
    254 2018-04-25 16:24:08,814  INFO [Thread-66] (EmployeeService.java:65) - tryTimes: 2
    255 2018-04-25 16:24:08,827  INFO [Thread-94] (EmployeeService.java:77) - oldMoney: 187
    256 2018-04-25 16:24:08,840  INFO [Thread-53] (EmployeeService.java:77) - oldMoney: 188
    257 2018-04-25 16:24:08,840  INFO [Thread-95] (EmployeeService.java:77) - oldMoney: 188
    258 2018-04-25 16:24:08,843  INFO [Thread-62] (EmployeeService.java:65) - tryTimes: 2
    259 2018-04-25 16:24:08,843  INFO [Thread-55] (EmployeeService.java:65) - tryTimes: 2
    260 2018-04-25 16:24:08,857  INFO [Thread-37] (EmployeeService.java:77) - oldMoney: 189
    261 2018-04-25 16:24:08,872  INFO [Thread-94] (EmployeeService.java:65) - tryTimes: 2
    262 2018-04-25 16:24:08,872  INFO [Thread-53] (EmployeeService.java:65) - tryTimes: 2
    263 2018-04-25 16:24:08,887  INFO [Thread-15] (EmployeeService.java:77) - oldMoney: 190
    264 2018-04-25 16:24:08,891  INFO [Thread-16] (EmployeeService.java:77) - oldMoney: 191
    265 2018-04-25 16:24:08,902  INFO [Thread-37] (EmployeeService.java:65) - tryTimes: 2
    266 2018-04-25 16:24:08,909  INFO [Thread-14] (EmployeeService.java:77) - oldMoney: 192
    267 2018-04-25 16:24:08,931  INFO [Thread-16] (EmployeeService.java:65) - tryTimes: 2
    268 2018-04-25 16:24:08,931  INFO [Thread-15] (EmployeeService.java:65) - tryTimes: 2
    269 2018-04-25 16:24:08,960  INFO [Thread-14] (EmployeeService.java:65) - tryTimes: 2
    270 2018-04-25 16:24:08,964  INFO [Thread-65] (EmployeeService.java:77) - oldMoney: 193
    271 2018-04-25 16:24:08,965  INFO [Thread-42] (EmployeeService.java:77) - oldMoney: 194
    272 2018-04-25 16:24:08,970  INFO [Thread-19] (EmployeeService.java:77) - oldMoney: 195
    273 2018-04-25 16:24:08,989  INFO [Thread-65] (EmployeeService.java:65) - tryTimes: 3
    274 2018-04-25 16:24:09,018  INFO [Thread-42] (EmployeeService.java:65) - tryTimes: 2
    275 2018-04-25 16:24:09,018  INFO [Thread-19] (EmployeeService.java:65) - tryTimes: 2
    276 2018-04-25 16:24:09,025  INFO [Thread-40] (EmployeeService.java:77) - oldMoney: 196
    277 2018-04-25 16:24:09,056  INFO [Thread-40] (EmployeeService.java:65) - tryTimes: 3
    278 2018-04-25 16:24:09,318  INFO [Thread-43] (EmployeeService.java:77) - oldMoney: 197
    279 2018-04-25 16:24:09,352  INFO [Thread-43] (EmployeeService.java:65) - tryTimes: 3
    280 2018-04-25 16:24:09,433  INFO [Thread-7] (EmployeeService.java:77) - oldMoney: 198
    281 2018-04-25 16:24:09,473  INFO [Thread-7] (EmployeeService.java:65) - tryTimes: 3
    282 2018-04-25 16:24:09,578  INFO [Thread-95] (EmployeeService.java:77) - oldMoney: 199
    283 2018-04-25 16:24:09,627  INFO [Thread-95] (EmployeeService.java:65) - tryTimes: 3
    

      

    可以看到,还是有一些线程会拿到相同的值,但是由于版本控制使得最终只有一根线程能够更新成功,其它更新失败的线程会继续尝试,最终能更新成功。

    第三部分 总结&对比

      悲观锁 乐观锁
    概念 查询时直接锁住记录使得其它事务不能查询,更不能更新 提交更新时检查版本或者时间戳是否符合
    语法 select ... for update 使用 version 或者 timestamp 进行比较
    实现者 数据库本身 开发者
    适用场景 并发量大 并发量小
    类比Java Synchronized关键字 CAS 算法
  • 相关阅读:
    Java基础面试题总结-编程题总结
    Linux下mysql的安装与卸载并且连接navicat详解(亲测可用)
    linux 下安装redis
    linux 下安装tomcat
    Linux系统下安装jdk及环境配置(两种方法)
    Servlet概述
    多线程之volatile关键字
    多线程之ThreadLocal
    多线程之synchronized实现原理
    线程池2
  • 原文地址:https://www.cnblogs.com/cnndevelop/p/12311310.html
Copyright © 2011-2022 走看看