1.排它锁

客户端1

1

2

3

4

5

6

7

set autocommit=0;

 

BEGIN;

 

SELECT * from bb_blog where id = 1 for update;

 

update bb_blog set title = 5525 where id = 1;

//这里没有提交事务 commit,因为提交之后就是解锁了

客户端1

1

SELECT * from bb_blog where id = 1 for update;

//不能看到数据,这里会被堵塞,甚至不能修改同样堵塞。

1

SELECT * from bb_blog where id = 1;

//可以看到数据,但是不能修改。

2.共享锁

客户端1

1

2

3

4

5

6

7

set autocommit=0;

 

BEGIN;

 

SELECT * from bb_blog where id = 1 lock in share mode;

 

update bb_blog set title = 5525 where id = 1; //如果不使用

//这里没有提交事务 commit,因为提交之后就是解锁了

客户端2

1

SELECT * from bb_blog where id = 1 lock in share mode;

//如果没有出现update修改操作,可以共享看到数据但是不能修改修改操作会被堵塞,如果客户端1使用了update操作,这里将会堵塞不能看到数据。

1

SELECT * from bb_blog where id = 1 lock;

//无论客户端1是否使用了update操作都可以共享看到数据(客户端1没update之前的老数据 而不是update之后的数据)。但是不能修改 修改操作会被堵塞。

总结:只要客户端1上了共享锁 客户端2无论是否使用 lock in share mode;都可以看到数据,但是不能操作。如果客户端1做了update操作,客户端2使用了lock in share mode;不能看到数据不能操作,直接select可以看到之前的老数据。

3.乐观锁

表示在查询数据表某一行记录时,很乐观的认为其他人不会在这个时候对这行数据进行update操作,只有在update的时候才会上锁认为别人也在操作这条数据。

乐观锁常实现方式通过version,在数据表中加一个字段version,需要操作数据的时候 先将他和其他数据一起取出,然后在update的时候where中加入version这个字段,并且修改的时候+1。如果这个字段被人改过了,就认为这条数据已经被人操作了。

4.悲观锁

表示无论在查询数据或者修改数据的时候都认为同时有人在修改数据,保证在查询的时候也只能是一个人在操作,一般是使用mysql本身的排它锁+事物的方式现实,

1

2

3

4

5

6

7

set autocommit=0;

 

BEGIN;

 

SELECT * from bb_blog where id = 1 for update; //排它锁的方式

 

update bb_blog set title = 5525 where id = 1;

这个时候 只能我在进行数据操作,其他人访问这条数据都是堵塞状态。

5.mysql innodb的行锁机制

如果字段上有主键索引,在使用update操作该数据的时候才会触发行锁机制,其他update的操作都会被堵塞,如果没有主键索引字段则会直接进行表锁。

悲观锁和乐观锁区别(需要结合其他自行实现):

悲观锁基本依靠数据库排它锁或者其他锁实现/或者redis等其他,乐观锁通过代码+字段实现。

悲观锁,无论是读还是写,都要上锁 通过for update。事物没有提交之前 只能有一个人能访问该数据。

乐观锁,数据只要没有出现update的操作,大家都可以访问该数据。

共享锁和排它锁区别总结(数据库自带锁):

使用了排它锁,就算是select读取操作同样会被堵塞。

使用了共享锁 读取操作可以进行,前提是上锁者没有进行update操作。