java多线程操作mysql,同时更新或者删除操作线程安全吗?

1.简单创建一张表

CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2.插入几条数据

INSERT INTO `user` VALUES (1, '张三', 18);
INSERT INTO `user` VALUES (2, '李四', 19);
INSERT INTO `user` VALUES (3, '王五', 18);
INSERT INTO `user` VALUES (4, '赵六', 18);
INSERT INTO `user` VALUES (5, '孙七', 19);
INSERT INTO `user` VALUES (6, '王八', 20);

3.开始测试,navicat新建查询,新建2个查询窗口
在这里插入图片描述
4.窗口1执行以下语句,开启事务,更新id=1的年龄

start TRANSACTION;
update user set age = 100 where id = 1;

窗口2执行以下语句,更新id=1的年龄

update user set age = 99 where id = 1;

窗口1执行结果
在这里插入图片描述
窗口2等待超时后的执行结果
在这里插入图片描述
看得出,一直等待了50多秒都没有获得锁,所以不会执行窗口2的更新语句,也就是更新同一条数据的时候是线程安全的,如果窗口2执行的时候,窗口1commit的话,窗口2便能更新成功。

虽然是线程安全的,可不要执行update …where id = xx。因为同时执行的话,前一条执行完后面一条也会执行,所以一般是更新的时候会加个乐观锁。比如这里,如果窗口1执行

update user set age = 100 where id = 1;

窗口2执行

update user set age = 99 where id = 1;

最终结果会是99
如果我们希望年龄更改后就不能再更改了,可以这样
窗口1

update user set age = 100 where id = 1 and age = 18;

窗口2

update user set age = 99 where id = 1 and age = 18;

这样年龄就只能更新一次了,这样才能应对java高并发问题。
不过千万要注意的是,读操作是不加锁的,更新的时候虽然加了写锁,但是读还是正常的,所以更新的时候进行读操作是线程不安全的,读取到的数据是旧的,如果只是纯粹的读取倒没什么影响,读取有滞后性很正常,就像秒杀商品,你看到的时候还有数量,但是下单后却发现卖完了

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值