事务并发解决方案
来源:互联网 发布:网络错误404是怎么办 编辑:程序博客网 时间:2024/06/05 01:54
设计目标
解决目前系统内部分业务使用 for update 锁单条或锁结果集合性能问题。
基本概念
for update: 数据库上锁关键字,在事务未提交之前其他需要更改相同记录的事务会排队等待。
设计方案
1.针对锁单条记录方案
1.数据库行锁机制 (悲观锁)
使用场景
1.订单状态变更场景,在状态变更SQL 语句后面加条件判断状态是否不等于更新目标状态,如果等于就代表已经更新过了。
例如: update table set status = 'fail' where status != 'fail'
2.库存加减场景, 在加减库SQL 语句采用在原字段递增或递减的方式
例如:update table set xxx = (xxx - 1) where xxx > 1 update table set xxx = (xxx - #{args}) where xxx > #{args}update table set xxx = (xxx + 1)
优缺点:
优点:相对于大事务重一开始就锁住(for update)需要的记录,在进行操作,到最后提交事务。 这种方式锁的成本低一些(只有在update时才会数据行锁)。
缺点:有局限性字段类型要支持加减,编码是需要明确知道流程走向和where条件值的判断。
2.基于数据版本号机制(乐观锁)
在需要锁的表加 version 字段,修改数据前先获取版本号,再执行修改语句判断版本号是否相同,如果不同则有其他任务修改过数据,此次修改失败可进行重试策略(定义一个重试次数超过重试次数还未竞争到锁提示系统繁忙)。
例如:select xxx, version from tableupdate set xxx = #{xxx} , version = (version+1) where version = #{version}
优缺点:
优点:采用版本号策略在高并发的情况下,可以避免行锁排队,(版本号过期where 条件匹配为0条)
缺点:并发情况下失败率较高,采用重试策略会增加数据查询量
3.分布式锁方案 (内存锁)
基于memcached, 或 redis 缓存服务加锁策略。
在操作数据库相关记录需要上锁时,针对此记录(key)在缓存服务里设置一个值并设置一定的失效时间(锁等待时长)。
如果设置成功代表拿到锁,此时进行业务想过操作,完毕或释放缓存服务里的锁。
如果设置失败,代表当前资源被占用,可重试去获取锁(定义获取锁重试次数)超过重试次数还未竞争到锁提示系统繁忙。
优缺点:
优点:将数据库的锁竞争压力转义到缓存服务器。
缺点:对于锁的key不好定义,且存在缓存系统宕机风险。
4.单机锁解决方案
单机使用JVM内存锁控制并发,并设置一定的锁超时
伪代码:
Lock lock = new ReentrantLock();for (int i = 0; i < 5; i++) {try {if (lock.tryLock(50, TimeUnit.MILLISECONDS)) {//TODO 处理逻辑 }} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}
优点:根据机器数来控制并发数
缺点:扩展机器带来并发数增高
2.针对锁结果集合的方案
参考方案 3.分布式锁方案 (内存锁)
需要定义锁的key。
- 事务并发解决方案
- 事务并发的可能问题与其解决方案
- 数据库并发事务中的问题与解决方案
- 分布式事务,高并发下分布式事务的解决方案
- 为什么Actor模型是高并发事务的终极解决方案?
- 为什么Actor模型是高并发事务的终极解决方案?
- 为什么Actor模型是高并发事务的终极解决方案
- 为什么Actor模型是高并发事务的终极解决方案?
- 并发事务
- 事务并发
- 深入理解分布式事务,高并发下分布式事务的解决方案
- 深入理解分布式事务,高并发下分布式事务的解决方案
- 深入理解分布式事务,高并发下分布式事务的解决方案
- 深入理解分布式事务,高并发下分布式事务的解决方案
- 深入理解分布式事务,高并发下分布式事务的解决方案
- 深入理解分布式事务,高并发下分布式事务的解决方案
- 深入理解分布式事务,高并发下分布式事务的解决方案
- 深入理解分布式事务,高并发下分布式事务的解决方案
- 某文件不在sudoers 中
- linux下install命令和cp命令的区别
- Python json 第三方库Demjson安装
- TeamTalk源码分析(六) —— 服务器端login_server源码分析
- 取址符的作用
- 事务并发解决方案
- mysql计算两个日期相减的方式
- arm汇编知识点
- 【机器学习】回归
- (Java ) ISBN号码
- Eclipse中安装和使用CheckStyle
- TLD 详细解析之 跟踪器
- kotlin 官方学习教程之语法
- Protocol Buffers Encoding