在后端开发中咱们不可避免的会碰见MySQL数据并发更新的状况,做为一名后端研发,如何解决这类问题也是必需要知道的,同时这也是面试中常常考察的知识点。html
SQL语句为以下时,是否会加锁?node
UPDATE table1 SET num = num + 1 WHERE id=1;复制代码
答案是不会git
实际上MySQL是支持给数据行加锁(InnoDB)的,而且在UPDATE/DELETE等操做时确实会自动加上排它锁。只是并不是只要有UPDATE关键字就会全程加锁,针对上面的MySQL语句而言,其实并不仅是一条UPDATE语句,而应该相似于两条SQL语句(伪代码):github
a = SELECT * FROM table1 WHERE id=1;
UPDATE table1 SET num = a.num + 1 WHERE id=1; 复制代码
其中执行SELECT语句时没有加锁,只有在执行UPDATE时才进行加锁的。因此才会出现并发操做时的更新数据不一致。缘由找到了,解决问题就不远了。而针对这类问题,解决的方法能够有2种:面试
SELECT ... LOCK IN SHARE MODE #共享锁,其它事务可读,不可更新
SELECT ... FOR UPDATE #排它锁,其它事务不可读写复制代码
SET AUTOCOMMIT=0;
BEGIN WORK;
a = SELECT num FROM table1 WHERE id=2 FOR UPDATE;
UPDATE table1 SET num = a.num + 1 WHERE id=2;
COMMIT WORK;复制代码
在具体更新数据的时候更新条件中会添加版本号信息,sql
对 for update上锁进行一次实践数据库
一个student表,其中有一条数据后端
开启两个client
并发
select name from student where id = 1 for update;复制代码
总的来讲,这2种方式均可以支持数据库的并发更新操做。但具体使用哪种就得看实际的应用场景,应用场景对哪一种支持更好,而且对性能的影响最小。性能
参考自: