您当前的位置: 首页 > 

石头wang

暂无认证

  • 5浏览

    0关注

    295博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

关于用select-for-update语句产生锁住记录不让其他事务(线程)修改的问题

石头wang 发布时间:2021-04-02 13:45:38 ,浏览量:5

背景

我们知道update库表里的一条数据会产生行锁(以mysql innodb为例),提交事务后才会释放行锁,在行锁阶段别的事务无法去修改同一条记录。

在 Navicat 和命令行中,执行完这条update的 SQL 就立即提交事务。但是在Java程序里,用 @Transactional 修饰的方法只有执行完毕后才会提交事务。

除了update 语句,select for update 语句也是可以产生行锁的(也不一定是行锁,也可能表锁),可以用于临时锁定一行记录不被修改。

今天研究的课题就是研究下 select for update 的细节

代码

直接上代码

  • Rest 接口
@RestController
public class TestRest {
    @Autowired
    @Qualifier("testService1Impl")
    private TestService testService1;
    @Autowired
    @Qualifier("testService2Impl")
    private TestService testService2;
    @Autowired
    @Qualifier("testService3Impl")
    private TestService testService3;
    @Autowired
    @Qualifier("testService4Impl")
    private TestService testService4;

    @GetMapping("/testSelectForUpdate1")
    public Object testSelectForUpdate1(@RequestParam Integer id) {
        return testService1.selectForUpdate(id);
    }
    @GetMapping("/update1")
    public String update1(@RequestParam Integer id) {
        String remark = new SimpleDateFormat("HH:mm:ss.SSS").format(new Date());
        return "affected:" + testService1.update(id, remark);
    }


    @GetMapping("/testSelectForUpdate2")
    public Object testSelectForUpdate2(@RequestParam Integer id) {
        return testService2.selectForUpdate(id);
    }
    @GetMapping("/update2")
    public String update2(@RequestParam Integer id) {
        String remark = new SimpleDateFormat("HH:mm:ss.SSS").format(new Date());
        return "affected:" + testService2.update(id, remark);
    }


    @GetMapping("/testSelectForUpdate3")
    public Object testSelectForUpdate3(@RequestParam Integer id) {
        return testService3.selectForUpdate(id);
    }
    @GetMapping("/update3")
    public String update3(@RequestParam Integer id) {
        String remark = new SimpleDateFormat("HH:mm:ss.SSS").format(new Date());
        return "affected:" + testService3.update(id, remark);
    }


    @GetMapping("/testSelectForUpdate4")
    public Object testSelectForUpdate4(@RequestParam Integer id) {
        return testService4.selectForUpdate(id);
    }
    @GetMapping("/update4")
    public String update4(@RequestParam Integer id) {
        String remark = new SimpleDateFormat("HH:mm:ss.SSS").format(new Date());
        return "affected:" + testService4.update(id, remark);
    }
}
  • Service实现类

其他 3 个Service实现类分别是:方法都去掉 @Transactional,去掉其中一个方法的 @Transactional

@Service
public class TestService1Impl implements TestService {
    @Autowired
    private TestMapper testMapper;

    @Transactional
    @Override
    public MyTable selectForUpdate(int id) {
        MyTable myTable = testMapper.selectForUpdate(id);
        int totalSecs = 20;
        for (int i = 0; i             
关注
打赏
1663722529
查看更多评论
0.1743s