PLSQL使用for update编辑数据库的坑

问题出现的场景

今天有个需求是对数据库中一张表进行相关的CRUD操作,刚开始的时候操作都没有,知道我测试删除功能的时候,页面点击删除没有任何反应。

问题追踪

使用debug模式启动项目,并且在删除逻辑开始的地方打上断点,在前端点击相关的删除按钮,后台并没有进入断点。由此得到可能是前端页面请求出现了错误。于是打开Chrome的开发者工具选到Network,查看那个删除的ajax请求信息。 结果如下:
在这里插入图片描述
遇到问题先问一波度娘,但是网上大多数的答案都是什么ajax请求跨域什么的,但是我本地跑的项目压根就没有跨域的场景,前后端都是一起的。于是放弃百度,回忆自己在这之前所做的操作。

找到问题

在做删除功能之前我是先做的新增的功能于是数据库中存在了很多不符合规定的数据。于是我使用的plsql对数据进行删除。具体的删除方法如下:

  • 步骤一:
    使用plsql中查询语句查询出所有数据。
select a.* from BPM_WISDOMINSPECT_BIDEXPERT a
order by wf_doccreated desc  for update
  • 步骤二
    在查询出来的结果中进行删除。
    在这里插入图片描述
    点击图片中小锁,然后选定指定行在点击左上角上的减号完成删除操作。单完成了所有的操作后点击左上角的√然后在点击plsql整个窗口左上角的那个提交按钮提交事务。

为了检验手动删除有没有出现问题,于是我再次使用了上述sql查询了下。发现数据一切正常。于是我在页面选中我要删除记录进行删除,这时候就出了文中刚开始出现的那种问题,浏览器没有任何反应。

得出结论

经过仔细的查看,原来使用for update进行查询,不管你是否进行了操作,只要执行了这条语句就会开启事务。因为我在查询后并没有提交事务,于是页面请求的删除操作就之一被阻塞了。当我在plsql中点击提交事务后,刚刚没有响应的页面完成了响应。

for update语句的替代方案

select rowid ,a.* from BPM_WISDOMINSPECT_BIDEXPERT a
order by wf_doccreated desc  

使用这种方式进行查询,一开始是不会开启事务的,只有你在查询出来的结果中删除了某些记录才需要提交事务。

for update执行机制

Select …for update(nowait)
Select * from tab1 for update
用户发出这条命令之后,oracle将会对返回集中的数据建立行级封锁,以防止其他用户的修改。
如果此时其他用户对上面返回结果集的数据进行dml或ddl操作都会返回一个错误信息或发生阻塞。

  • 1:对返回结果集进行update或delete操作会发生阻塞。
  • 2:对该表进行ddl操作将会报:Ora-00054:resource busy and acquire with nowait specified.
原因分析

此时Oracle已经对返回的结果集上加了排它的行级锁,所有其他对这些数据进行的修改或删除操作都必须等待这个锁的释放,产生的外在现象就是其他的操作将发生阻塞,这个这个操作commit或rollback.

同样这个查询的事务将会对该表加表级锁,不允许对该表的任何ddl操作,否则将会报出ora-00054错误::resource busy and acquire with nowait specified.

发布了4 篇原创文章 · 获赞 1 · 访问量 1454
App 阅读领勋章
微信扫码 下载APP
阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览