oracle的nlslang,一个oracle并发性问题的分析和解决

1问题背景

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

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

2相关代码

oracle存储过程部分代码

--今天更换任务的数量

haveChanged(userID, gradeID, dirCnt);

---如果今天更换任务个数小于1

if 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);

---如果今天更换任务个数小于1

if 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操作时,会先检查表中是否数据被锁,如果有数据被锁,则等待

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值