并发修改的数据在MySQL等关系型数据库使用的锁

文章讨论了在单机和集群部署环境下,如何使用jvm本地锁和MySQL锁来实现线程同步。本地锁在多例模式和集群部署中可能失效,而MySQL的更新操作自带事务、悲观锁和乐观锁能提供不同级别的数据一致性保证。在高并发场景下,乐观锁可能需要多次重试,而悲观锁能确保序列化执行。在分布式环境中,MySQL的锁也可作为分布式锁使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 单机部署的应用
    一、可以使用jvm本地锁,比如synchronized来同步代码块或者@Synchronized来将整个方法变为同步方法,或者使用ReentrantLock lock() unlock() 锁定代码。
    jvm本地锁失效的三种情况:
    1、被锁定(或者说被同步)的代码块所在方法如果是多例模式或者此方法所在控制器是多例模式:因为多例模式下多个线程不会公用一个控制器,用的不是同一个资源,jvm锁就会失效。
    2、集群部署,很明显不是同一个进程,甚至不是同一台服务器,jvm本地锁自然失效,本地锁只能对统一进程内的多个线程起到锁定同步作用。
    3、被锁定方法或者代码块外层使用事务,且被锁定代码包含查询和查询,且查询的SQL没有使用悲观锁。比如第一个线程释放锁后还未提交事务,第二个线程获得锁,执行查询,查询到第一个线程操作前的数据,继续往下执行。它应该查询到第一个线程提交后的数据,这样才起到线程在执行这段代码时序列化的作用。
    二、也可以使用MySQL的锁:
    1、用一条SQL完成更新。比如:update stock set count = count - 1 where id = ‘xxx’。MySQL默认每条更新数据库的操作都会自动加上事务。
    2、用悲观锁,先用select…for update 查询,在更新。注意这里两个对数据库的操作一个查询,一个更新。要放在一个事务中进行才能使用到select…for update的悲观锁。方法上要加上@Transactional。
    3、用乐观锁,乐观锁就是在数据库表上添加一个version字段,每次更新都对这个字段+1,每次更新前先读出version的值,更新时将version也一并作为更新条件,如果不成功再执行上面的查询更新,直到成功为止。并发写数据库很多的情况下,乐观锁要不断地重试才能成功,吞吐量反而不如悲观锁。

  • 集群部署的应用
    分布式应用环境中MySQL的锁也能起到锁定数据的作用,也能当作分布式锁使用。所以如果是集群部署,也可以使用MySQL的锁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值