非常奇怪的事务回滚问题

langziqian 2009-09-28 10:24:25
存储 sp_A 调用存储sp_B
sp_A的代码:

exec sp_B @t
select * from tt

sp_B的代码:

begin try
begin tran aa1
insert into tt
select @t
commit tran aa1
end try
begin catch
rollback tran aa1
end catch

问题来了:大多情况下都正常,但是最近发现当sp_B中插入表tt失败时,sp_A中仍然能够拿到插入的数据;
如: insert into tt select 100,当tt被锁住,sp_B会回滚,tt中不存在100这个记录,但是sp_A却把100返回了

请高手解惑
...全文
132 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
langziqian 2009-10-02
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 7761098 的回复:]
在sp_B中加一个out参数,判断成功执行之后sp_A才读取
[/Quote]

试一下
lg314 2009-10-01
  • 打赏
  • 举报
回复
exec sp_B @t 
if (@@trancount<>0) rollback tran
select * from tt

弄错了
lg314 2009-10-01
  • 打赏
  • 举报
回复
exec sp_B @t 
if (@@trancount>1) rollback tran
select * from tt

这样试试
lg314 2009-10-01
  • 打赏
  • 举报
回复
可能是孤立事务了,也遇到这种问题,很有意思,已经插入了一个数据,然后select也查出这些了,后来运行了一次rollback trans,全给滚过去了,哈哈。
langziqian 2009-10-01
  • 打赏
  • 举报
回复
自己顶一下
littlegang 2009-09-30
  • 打赏
  • 举报
回复
lz 能肯定是 用了 select * from tt ,而没有加 with (nolock) ?
难道嵌套存储过程的就是不隔离的?没道理啊
7761098 2009-09-30
  • 打赏
  • 举报
回复
在sp_B中加一个out参数,判断成功执行之后sp_A才读取
langziqian 2009-09-30
  • 打赏
  • 举报
回复
现在的问题是发生了脏读
怎么避免呢
soft_wsx 2009-09-29
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 langziqian 的回复:]
soft_wsx
感觉就是你说的那种情况

怎么避免呢
[/Quote]用NOLOCK是避免不了的!嘻嘻!

SELECT * FROM TB(NOLOCK)差不多了!因为发生赃读不是很多!除非像移动,电信等超大企业!

you_tube 2009-09-29
  • 打赏
  • 举报
回复
select * from tt (nolock)
  • 打赏
  • 举报
回复
测试之后,没有问题啊。按道理是不应该读取出来的。
你的语句里面没有写tt表被锁住后,sp_B会回滚啊,应该会一直等待。如果其他语句在sp_B等待的时候把tt已经释放掉了,还是会显示出结果的。

楼主看看会不会有这样的情况发生
langziqian 2009-09-29
  • 打赏
  • 举报
回复
soft_wsx
感觉就是你说的那种情况

怎么避免呢
soft_wsx 2009-09-29
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 langziqian 的回复:]
楼上的
解释一下(nolock)
[/Quote]可能会读取未提交事务中的数据
soft_wsx 2009-09-29
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 langziqian 的回复:]
楼上的
解释一下(nolock)
[/Quote]不要发出共享锁,并且不要提供排它锁。当此选项生效时,可能会读取未提交的事务或一组在读取中间回滚的页面。有可能发生脏读。仅应用于 SELECT 语句。
langziqian 2009-09-29
  • 打赏
  • 举报
回复
楼上的
解释一下(nolock)
--小F-- 2009-09-28
  • 打赏
  • 举报
回复

检查死锁用sp_who_lock过程
sp_who_lock

查看SQL Server数据库里的锁的情况
sp_lock

都试下
ws_hgo 2009-09-28
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 langziqian 的回复:]
是表级的锁
但是没有查出为什么锁住了

[/Quote]
你把这个表的相关信息调出来看下
langziqian 2009-09-28
  • 打赏
  • 举报
回复
是表级的锁
但是没有查出为什么锁住了
Zoezs 2009-09-28
  • 打赏
  • 举报
回复
你说的锁住是什么意思?
TABLOCK?
Zoezs 2009-09-28
  • 打赏
  • 举报
回复
应该是这样吧?

select * from tt
where id=@t
加载更多回复(1)
基于springcloud+springboot+nacos+openFeign的分布式事务组件seata项目源码.zip 介绍 分布式事务组件seata的使用demo,AT模式、TCC模式,集成springboot、springcloud(nacos注册中心、openFeign服务调用、Ribbon负载均衡器)、spring jpa,数据库采用mysql demo中使用的相关版本号,具体请看代码。如果搭建个人demo不成功,验证是否是由版本导致,版本稍有变化可能出现相关组件的版本不一致便会出现许多奇怪问题 seata服务端 1.3 Nacos服务端 1.1.4 spring-cloud-alibaba-dependencies 2.1.0.RELEASE springboot 2.1.3.RELEASE springcloud Greenwich.RELEASE 软件架构 软件架构说明 springcloud-common 公共模块 springcloud-order-AT 订单服务 springcloud-product-AT 商品库存服务 springcloud-consumer-AT 消费调用者 springcloud-business-Tcc 工商银行服务 springcloud-merchants-Tcc 招商银行服务 springcloud-Pay-Tcc 消费调用者 AT模式:springcloud-order-AT,springcloud-product-AT,springcloud-consumer-AT为AT模式Dome;模拟场景用户购买商品下单; 调用流程springcloud-consumer-AT调用订单服务创建订单(新增一条数据到订单表);在调用商品库存服务扣减商品库存数量(修改商品库存表商品数量);最后出现异常则统一回滚,负责统一提交; 第一阶段:准备阶段(prepare)协调者通知参与者准备提交订单,参与者开始投票。协调者完成准备工作向协调者回应Yes。 第二阶段:提交(commit)/回滚(rollback)阶段协调者根据参与者的投票结果发起最终的提交指令。如果有参与者没有准备好则发起回滚指令。

22,207

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧