一、什么是共享锁,什么是排他锁?
1、共享锁:
共享锁就是多个事务对于同一数据共享一把锁,都能访问到数据,但是只能读不能修改。共享锁又称为读锁,简称S锁。
原理:一个事务获取了一个数据行的共享锁,其他事务能获得该行对应的共享锁,但不能获得排他锁,即一个事务在读取一个数据行的时候,其他事务也可以读,但不能对该数据行进行增删改(因为增删改都是自动加排它锁)。
2、排他锁:
排他锁就是不能与其它锁并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他
锁的事务是可以对数据就行读取和修改。排他锁又称为写锁,简称X锁。
原理:一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁(排他锁或者共享锁),即一个事务在读取一个数据行的时候,其他事务不能对该数据行进行增删改,不加锁的查是可以的,加锁的查是不可以的。
3、如何设置共享锁和排他锁?:
设置共享锁:SELECT ... LOCK IN SHARE MODE; 共享锁都是行锁
设置排他锁:SELECT ... FOR UPDATE; 排它锁可以使行锁也可以是表锁
对于共享锁大家可能很好理解,就是多个事务只能读数据不能改数据;排他锁指的是一个事务在一行数据加上排他锁后,其他事务不能再在其上加其他的锁。mysql InnoDB引擎默认的修改数据语句,update,delete,insert都会自动给涉及到的数据加上排他锁,select语句默认不会加任何锁类型,所以加过排他锁的数据行在其他事务中是不能修改数据的,也不能通过for update和lock in share mode锁的方式查询数据,但可以直接通过select ...from...查询数据,因为普通查询没有任何锁机制。
4、注意点:
①、对于select 语句,innodb不会加任何锁,也就是可以多个并发去进行select的操作,不会有任何的锁冲突,因为根本没有锁。
②、对于insert,update,delete操作,innodb会自动给涉及到的数据加排他锁,只有查询select需要我们手动设置排他锁。
二、什么是意向共享锁,什么是意向排他锁?
1、意向共享锁:
简称IS,其作用在于:通知数据库接下来需要施加什么锁并对表加锁。如果需要对记录A加共享锁,那么此时innodb会先找到这张表,对该表加意向
共享锁之后,再对记录A添加共享锁。
2、意向排他锁:
简称IX,其作用在于:通知数据库接下来需要施加什么锁并对表加锁。如果需要对记录A加排他锁,那么此时innodb会先找到这张表,对该表加意向
排他锁之后,再对记录A添加排他锁。
意向共享锁和意向排它锁是数据库主动加的,不需要我们手动处理
三、共享锁和意向共享锁,排他锁与意向排他锁的区别?
共享锁和排他锁,系统在特定的条件下会自动添加共享锁或者排他锁,也可以手动添加共享锁或者排他锁。
意向共享锁和意向排他锁都是系统自动添加和自动释放的,整个过程无需人工干预。
共享锁和排它锁,可能锁定的是表,也可能锁定的是行
例如
SELECT count(*) as total FROM test WHERE username = "mraz" FOR UPDATE
当username是主键时,锁定的是行锁,
当username不是主键时,是表锁
InnoDB行锁是通过索引上的索引项来实现的,这一点MySQL与Oracle不同,后者是通过在数据中对相应数据行加锁来实现的。 InnoDB这种行锁实现特点意味者:只有通过索引条件检索数据,InnoDB才会使用行级锁,否则,InnoDB将使用表锁!
在实际应用中,要特别注意InnoDB行锁的这一特性,不然的话,可能导致大量的锁冲突,从而影响并发性能。
意向共享锁和意向排他锁锁定的是表。
意向锁是InnoDB自动加的,不需用户干预。对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及及数据集加排他锁(X);对于普通SELECT语句,InnoDB不会任何锁;事务可以通过以下语句显示给记录集加共享锁或排锁。
用SELECT .. IN SHARE MODE获得共享锁,主要用在需要数据依存关系时确认某行记录是否存在,并确保没有人对这个记录进行UPDATE或者DELETE操作。但是如果当前事务也需要对该记录进行更新操作,则很有可能造成死锁,对于锁定行记录后需要进行更新操作的应用,应该使用SELECT ... FOR UPDATE方式获取排他锁。