什么是锁?
锁是在并发情况下控制操作的顺序执行,以此保证数据安全的变动。
悲观锁:
认为被他保护的数据是极其不安全的,随时都可能发生改变,一个事务拿到悲观锁后,其他任何事务都不能对该数据进行修改,只能等待锁被释放才可以执行。
数据库中的行锁、表锁、读锁、写锁以及以synchronized实现的锁都是悲观锁
悲观锁的实现方式
一般使用 select ****** for update 进行加锁操作,当一个事务使用这种方式进行了加锁操作后,会对数据库中的表或某些行数据进行锁定,锁定规则:
select * from user for update 是锁表
select * from user limit 0,1 for update 锁定查询出的数据
select * from user where id = 1 for update id是主键,锁定查询出的数据
select * from user where name='张三' for update name不是主键,锁定整张表
select * from user where name='张三' limit 0,1 for update name不是主键,锁定查询出的数据
当锁定了某些行数据时候,其他的事务(主要是DML语句)不能对锁定的数据进行操作,但是查询语句(DQL语句)是可以进行查询的,注意查询语句不能有 for update ,因为这会去有进行加锁操作,
只会等待当前事务释放悲观锁后,下一个事务才会进行操作,当然如果有等待过期时间也会导致报错出现。
悲观锁通过两个窗口来测试结果如下:
乐观锁:
乐观锁“乐观”地认为数据不会频繁的变动,可以多个事务同时对数据进行修改,那么如何保证数据的顺序变动呢,乐观锁通常是在表中新增一个版本字段version或者时间戳timestamp;以时间戳举例,当有事务开始时,取出时间戳 t1,当完成改动数据后,需要再次查出对应的时间戳 t2, 如果 t1=t2,就说明数据改动期间,没有其他事务对该数据进行了修改,就允许此次对数据的更改,同时更新时间戳字段的值,如果 t1 不等于 t2,说明其他事务已经对此数据进行了修改,那么不允许本次修改更新到表中,本次更新失败。