在并发的情况下,程序事务和数据库事务是怎么运行的?

发布于 2022-09-02 23:41:19 字数 432 浏览 19 评论 0

@Transactional
public void selectAndUpdate() {
    status = select ... for update;
    if(status!="初始值") {
        return;
    }
    
    //逻辑开始
    程序逻辑 ...
    举例:用户支付
    1.生成用户签名
    2.发起用户支付到第三方
    //逻辑结束
    
    update status语句...
}

如果利用这种方式来控制并发会有什么问题?另外我还想问大家的是:多个线程的话,会不会导致当一个线程执行到程序逻辑那块的时候,资源被另一个线程抢去的可能?导致另一个线程进入这个方法,发现状态还是没有被改变,然后又进入程序逻辑这块,导致两个线程都执行了一遍吗?数据库的一个事务没有完成的话,会让另外一个线程的事务进入吗?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浅忆 2022-09-09 23:41:24

for update的缺点@Hisoka已经说了,for update除了会阻塞其它线程以外,加锁的过程对数据库的性能损耗也是很大的。
所以推荐使用乐观锁来解决,因为程序逻辑这块都是在内存中操作不涉及原始的数据,所以只需要在update status语句...这里使用乐观锁来控制状态就行了

这种方式是使用悲观锁来实现并发控制,瓶颈在于性能,另外就是for update 不带上nowait会导致线程等待不会快速失败,加了锁之后就不会出现被其他线程抢去的情况了,另外事务有隔离级别和传播行为的配置,不同设置有不同的结果,推荐找资料了解下先

乱了心跳 2022-09-09 23:41:24

for update 是用于解决高并发场景的问题,采用了分布式锁的机制实现的。第一条for update语句执行的手,后面的sql语句会sleep等待,直到第一条sql语句commit执行成功并提交后,才回去执行下一条语句。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文