加入收藏 | 设为首页 | 会员中心 | 我要投稿 武汉站长网 (https://www.027zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

Mysql事务中Update是否会锁表?

发布时间:2022-12-12 14:04:57 所属栏目:MySql教程 来源:转载
导读: 两种情况:
1.带索引 2.不带索引
前提介绍:
方式:采用命令行的方式来模拟
1.mysq由于默认是开启自动提交事务,所以首先得查看自己当前的数据库是否开启了自动提交事务。
命令:select @@

两种情况:

1.带索引 2.不带索引

前提介绍:

方式:采用命令行的方式来模拟

1.mysq由于默认是开启自动提交事务,所以首先得查看自己当前的数据库是否开启了自动提交事务。

命令:select @@autocommit;

结果如下:

+————–+| @@autocommit |+————–+| 0 |+————–+

如果是1,那么运行命令:set autocommit = 0;设置为不开启自动提交

2.当前的数据库表格式如下

tb_user | CREATE TABLE `tb_user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(32) DEFAULT NULL, `phone` varchar(11) DEFAULT NULL, `operator` varchar(32) DEFAULT NULL, `gmt_create` datetime DEFAULT NULL, `gmt_modified` datetime DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8

显然除了主键,我没有加任何索引

实际例子:

1.没有索引

运行命令:begin;开启事务,然后运行命令:update tb_user set phone=11 where name=”c1″;修改,先别commit事务。

再开一个窗口,直接运行命令:update tb_user set phone=22 where name=“c2”;会发现命令卡住了,但是当前面一个事务通过commit提交了,命令就会正常运行结束,说明是被锁表了。

2.给name字段加索引

create index index_name on tb_user(name);

然后继续如1里面的操作,也就是一个开启事务,运行update tb_user set phone=11 where name=”c1″;先不提交

然后另一个运行update tb_user set phone=22 where name=”c2″;发现命令不会卡住,说明没有锁表

但是如果另一个也是update tb_user set phone=22 where name=”c1″;更新同一行,说明是锁行了

3.总结

如果没有索引,所以update会锁表mysql索引表,如果加了索引,就会锁行

到此这篇关于Mysql事务中Update是否会锁表的文章就介绍到这了,更多相关Mysql事务Update锁表内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

事务/forupdate会锁表吗

如果条件中确定使用了索引,则会锁该行,如没有索引或没使用到索引,则会锁表。 是否使用到索引,利用trace工具判断,这里不做叙述。

但此时不能判断是行锁还是表锁。将session1提交后,session2随即成功提交,这里阻塞了20s左右session2修改其他数据正常执行,说明锁的是行锁,不是表锁。session2查询操作正常,因为普通读时由于mysql的mvcc机制会使用的是快照度,所以不会阻塞。 mvcc当前读与快照读及其相关原理这里不做叙述注:session1此时未提交session2修改当前数据被阻塞,因为修改属于特殊读这里会使用当前读,修改阻塞说明session1事务加了锁。

但此时不能判断是行锁还是表锁。将session1提交后,session2随即成功提交,这里阻塞了20s左右session2修改其他数据被阻塞,说明锁的是表锁,不是行锁。将session1提交后,session2随即成功提交,这里阻塞了20s左右session2查询操作正常,因为普通读时由于mysql的mvcc机制会使用的是快照度,所以不会阻塞。

mvcc当前读与快照读及其相关原理这里不做叙述注:for update只有在begin commit,也就是事务之间才会起作用,如果发现两个session都成功对一条数据加锁成功,注意看下是否有没有开启事务。 先打开两个连接session 注:session1此时未提交由于session1加了锁,session2查询加锁被阻塞,但此时不能判断是行锁还是表锁。将session1提交后,session2随即成功加锁,这里阻塞了20s左右session2加锁其他数据正常执行,说明锁的是行锁,不是表锁。

session2修改当前数据被阻塞session2修改其他数据正常执行注:session1此时未提交由于session1加了锁,session2查询加锁被阻塞,但此时不能判断是行锁还是表锁。将session1提交后,session2随即加锁成功,这里阻塞了20s左右session2加锁其他数据也被阻塞,说明锁的是表锁,不是行锁。将session1提交后,session2随即加锁成功,这里阻塞了20s左右session2修改当前数据被阻塞,但此时不能判断是行锁还是表锁。

将session1提交后,session2随即修改成功,这里阻塞了20s左右session2修改其他数据同样被阻塞,说明锁的是表锁,不是行锁。

MySQL – for update 行锁 表锁

for update 的作用是在查询的时候为行加上排它锁,当一个事务的操作未完成时候,其他事务可以读取但是不能写入或更新。 它的典型使用场景是 高并发并且对于数据的准确性有很高要求 ,比如金钱、库存等,一般这种操作都是很长一串并且开启事务的,假如现在要对库存进行操作,在刚开始读的时候是1,然后马上另外一个进程将库存更新为0了,但事务还没结束,会一直用1进行后续的逻辑,就会有问题,所以需要用for upate 加锁防止出错。

只在可重复读或以上隔离级别下的特定操作才会取得 gap lock 或 next-key lock,在 Select、Update 和 Delete 时,除了基于唯一索引的查询之外,其它索引查询时都会获取 gap lock 或 next-key lock,即锁住其扫描的范围。主键索引也属于唯一索引,所以主键索引是不会使用 gap lock 或 next-key lock for update 仅适用于InnoDB,并且必须开启事务,在begin与commit之间才生效。 select 语句默认不获取任何锁,所以是可以读被其它事务持有排它锁的数据的! InnoDB 既实现了行锁,也实现了表锁。 当有明确指定的主键/索引时候,是行级锁,否则是表级锁 假设表 user,存在有id跟name字段,id是主键,有5条数据。

update同张表不同数据会锁表么

当然会,select要获得共享锁,update要获得排他锁,排他锁与其他锁都冲突可以用select * from tb(nolock) 指定查询不占用锁资源,就不会冲突了。多线程访问会抢夺资源,A线程先抢占了资源,这时候B线程进来了,在A线程没有完成事务之前,会阻塞B去获取资源的。

如果此时B在等待A的事务完成,但是A又依赖B的事务完成,这就造成了循环依赖。这个时候就会死锁,双方都在等待。其他线程也没有办法获取资源。

mysql update会锁表吗

有一个任务序列控制sql语句的执行,第一次有select的语句查询表a,mysql服务器在执行select之前将表a加读锁,第二次又有一条select语句查询表a, mysql服务器发现在任务序列中有表a的读锁,也就是同时还有一个sql查询表a,读锁不会影响这条sql语句,当有一条update或者insert语句对表a操作时,mysql服务器会对表a加写锁,以此提示之后的对表a操作的sql语句等待写锁解锁后在执行,以免造成写入与读取的混乱

mysql select for update会锁表吗

这个完全取决于表采用的是什么存储引擎。以常见的存储引擎innodb和myisam为例:对于myisam的表select是会锁定表的,会导致其他操作挂起,处于等待状态。

(编辑:武汉站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!