博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个oracle并发性问题的分析和解决
阅读量:6229 次
发布时间:2019-06-21

本文共 1824 字,大约阅读时间需要 6 分钟。

hot3.png

1问题背景

有一个任务系统,限定每天只有两个任务,允许用户每天更换一次任务,在更换任务的同时,创建一个新的任务。

问题:发现一些用户每天的任务数超过了两个的限制,而且这些任务中,存在更换任务的情况

2相关代码

oracle存储过程部分代码

--今天更换任务的数量haveChanged(userID, gradeID, dirCnt); ---如果今天更换任务个数小于1if dirCnt<1 then               --查询任务的的状态  select task_state    into taskState    from user_task_info   where user_id = userID     and task_id = taskID;    --如果任务状态taskState = 0,表示任务进行中,可以进行更换任务  if taskState = 0 then          --修改任务状态     update user_task_info        set task_state = 3, m_time = sysdate      where user_id = userID        and task_id = taskID;          --1.commit;          --创建一个任务     initUserTask(userID, gradeID);          --2.commit;   end if;end if;

表面看上面的程序,应该是没有问题

1首先检查今天是否更换过任务

2如果没有更换过任务,检查更换任务的任务状态

3如果任务处于进行中,修改任务状态为更换,调用initUserTask存储过程创建一个新任务

问题分析:一般存储过程执行速度都是非常快的,都毫秒级别的,所以大部分用户更换任务都是没有问题的。

但是程序有严重的并发问题,当用户第一次请求没有commit之前,用户又来一次请求,就会造成创建多个任务

调度时刻 请求1 请求2
T1 查询今日是否更换过任务
T2 查询当前任务是否允许更新
T3 修改任务状态
T4  创建一个新任务
T5
查询今日是否更换过任务
T6
查询当前任务是否允许更新

T7

commit

T8

修改任务状态

T9

创建一个新任务

T10

commit

commit放在修改任务状态之后,或者创建任务之后都是一样

当用户第一个请求没有commit之前,第二个请求只要能进来,就会造成多创建任务

3解决方法

--今天更换任务的数量haveChanged(userID, gradeID, dirCnt); ---如果今天更换任务个数小于1if dirCnt<1 then             ---如果任务状态为0进行中时,更新任务状态3表示为更换任务  update user_task_info   set task_state = 3, m_time = sysdate  where task_state=0   and user_id = userID   and task_id = taskID;    ---查看sql执行条数  rows := SQL%ROWCOUNT;    ---1.commit;    ---如果任务更换成功 创建一个任务  if rows=1 then   initUserTask(userID, gradeID);  end if;    ---2.commit;end if;

解决方法:

第一个请求执行update操作时,oracle会进行锁数据操作

第二个请求update操作相同记录时,发现数据已锁,会处于等待状态。

当第一个请求修改任务状态后,rows=1,创建新任务,事务提交后,数据解锁

第二个请求执行update操作时,数据已经不满足查询条件,rows=0就无法创建任务

4总结

在oracle中,事务没有提交之前,update和delete为锁数据操作,如果操作的不是同一条数据,可以同时进行操作

insert为锁表操作,在向一个表insert操作时,会先检查表中是否数据被锁,如果有数据被锁,则等待

如果没有数据被锁,则进行锁表操作

转载于:https://my.oschina.net/lujianing/blog/270955

你可能感兴趣的文章
非监督学习算法:异常检测
查看>>
jquery的checkbox,radio,select等方法总结
查看>>
Linux coredump
查看>>
Ubuntu 10.04安装水晶(Mercury)无线网卡驱动
查看>>
Myeclipes快捷键
查看>>
我的友情链接
查看>>
ToRPC:一个双向RPC的Python实现
查看>>
我的友情链接
查看>>
nginx在reload时候报错invalid PID number
查看>>
神经网络和深度学习-第二周神经网络基础-第二节:Logistic回归
查看>>
Myeclipse代码提示及如何设置自动提示
查看>>
c/c++中保留两位有效数字
查看>>
ElasticSearch 2 (32) - 信息聚合系列之范围限定
查看>>
VS2010远程调试C#程序
查看>>
[MicroPython]TurniBit开发板DIY自动窗帘模拟系统
查看>>
由String类的Split方法所遇到的两个问题
查看>>
Python3.4 12306 2015年3月验证码识别
查看>>
从Handler.post(Runnable r)再一次梳理Android的消息机制(以及handler的内存泄露)
查看>>
windows查看端口占用
查看>>
Yii用ajax实现无刷新检索更新CListView数据
查看>>