1:悲观锁
1.1 特点:
每次查询都会进行锁行,怕“其他人”进行数据的修改。
1.2 实现步骤:
步骤1:开启事务test1,并对id=2的记录进行查询,并加锁,如:
步骤2:在事务test1没有进行commit的情况下,开启事务test2,并对id=2的记录进行修改,看执行结果
最终执行结果显示获取锁超时。
而在获取锁的过程中,执行 show processlist 命令可以看到:修改id=2的sql命令一直在等待锁。
而由于事务test1我没有commit,因此事务test2是获取不到锁的,因此就超时了。
步骤3:当我事务test1进行commit之后,我在事务test2中进行id=2的记录的修改操作时会是什么情况:
最终可以看到在事务test1进行commit之后,事务test2的修改操作终于成功了。
1.3 总结:
在事务中执行 select * from table where id = ? for update 并没有进行commit时,id = ? 的记录将进行锁行,另外一个事务想要修改 id = ? 的记录将会一直阻塞直至事务超时。
2:乐观锁
2.1 特点:
1:适用于读多于写的情况。
2:不会锁行,乐观主义。
2.2 实现方式:
常见的就是增加version字段或时间戳字段,每次修改都进行这个字段的更新。
2.3 那么如何解决多个人同时进行修改/新增/删除等操作时,最终只有一个执行成功?
我这里采用version的方式进行演示,测试步骤如下:
2.3.1:事务1的 DDL
2.3.2:事务2的 DDL
2.3.3:流程图
当事务1和事务2同时修改id=2 and version = 1 的记录的时候,最终事务1成功修改,而到事务2进行修改时符合条件的记录已经不存在了,因此修改失败!!
流程图如下:
结果:通过控制version,可以合理的解决资源竞争问题。
在日常开发中,可以利用事务的一致性,做更多的判断及操作。