请高手进来看看!!

u011165216 2014-06-20 08:11:16
我想用时间戳来解决在Read Committed下写覆盖的问题。
sql语句如下:

事务1:
use tcmanagement
begin tran
select * from tc where cno=0002
update tc set period=30 where cno=0002
commit tran

事务2:
use tcmanagement
begin tran
declare @t1 timestamp
declare @t2 timestamp
select @t1=t from tc where cno = 0002
select * from tc where cno=0002
select @t2=t from tc where cno = 0002
if (@t1=@t2)
begin
update tc set period=40 where cno=0002
end
else
begin
print '已更新过此数据!'
end
commit tran

假设我首先执行事务1中的
use tcmanagement
begin tran
select * from tc where cno=0002

再执行事务2中的
use tcmanagement
begin tran
declare @t1 timestamp
declare @t2 timestamp
select @t1=t from tc where cno = 0002
select * from tc where cno=0002

接着执行事务1中的
update tc set period=30 where cno=0002
commit tran

最后执行事务2的
select @t2=t from tc where cno = 0002
if (@t1=@t2)
begin
update tc set period=40 where cno=0002
end
else
begin
print '已更新过此数据!'
end
commit tran

但这时报错,说未定义变量@t1,@t2。这是因为局部变量问题。
那请问要怎么改?
如果改不了,那要怎样才能实现用时间戳来解决在Read Committed下写覆盖的问题啊?
...全文
96 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
u011165216 2014-06-22
  • 打赏
  • 举报
回复
引用 5 楼 tcmakebest 的回复:
我好奇的是楼主如何来分段执行,分段执行如何保持事务不中断? 我感觉是事务被中断了.
就把要引用的语句选中执行啊。。 其实我的这个问题是因为局部变量 或者你知不知道除了用updlock来解决,还有什么方法来在Read Committed级别下能解决写覆盖问题
专注or全面 2014-06-21
  • 打赏
  • 举报
回复
你在第二个存储过程中的方法我觉得不对 为什么是两次判断,而不是三次,四次? select @t1=t from tc where cno = 0002 select * from tc where cno=0002 select @t2=t from tc where cno = 0002 if (@t1=@t2) 因为执行到这里的时候,即便是判断条件成立,另外的进程完全可以独占 cno = 0002的这条记录,然后更改他 还是会产生所谓的写覆盖 加入有高并发的情况,时间戳也判断不出来 2014-06-21 10:43:43.7070000 2014-06-21 10:43:43.7070000 2014-06-21 10:43:43.7070000 2014-06-21 10:43:43.7100000 2014-06-21 10:43:43.7100000 2014-06-21 10:43:43.7100000 2014-06-21 10:43:43.7100000 2014-06-21 10:43:43.7100000 2014-06-21 10:43:43.7130000 2014-06-21 10:43:43.7130000 2014-06-21 10:43:43.7130000 2014-06-21 10:43:43.7130000
tcmakebest 2014-06-21
  • 打赏
  • 举报
回复
我好奇的是楼主如何来分段执行,分段执行如何保持事务不中断? 我感觉是事务被中断了.
u011165216 2014-06-21
  • 打赏
  • 举报
回复
引用 3 楼 x_wy46 的回复:
你在第二个存储过程中的方法我觉得不对 为什么是两次判断,而不是三次,四次? select @t1=t from tc where cno = 0002 select * from tc where cno=0002 select @t2=t from tc where cno = 0002 if (@t1=@t2) 因为执行到这里的时候,即便是判断条件成立,另外的进程完全可以独占 cno = 0002的这条记录,然后更改他 还是会产生所谓的写覆盖 加入有高并发的情况,时间戳也判断不出来 2014-06-21 10:43:43.7070000 2014-06-21 10:43:43.7070000 2014-06-21 10:43:43.7070000 2014-06-21 10:43:43.7100000 2014-06-21 10:43:43.7100000 2014-06-21 10:43:43.7100000 2014-06-21 10:43:43.7100000 2014-06-21 10:43:43.7100000 2014-06-21 10:43:43.7130000 2014-06-21 10:43:43.7130000 2014-06-21 10:43:43.7130000 2014-06-21 10:43:43.7130000
我原本想的是当事务1的 update tc set period=30 where cno=0002 commit tran 执行完后,这条记录的时间戳就会有变化,然后在事务2中根据时间戳前后的不同来比较 那假如时间戳不行,你觉得除了加锁,还能用什么办法来在Read Committed级别下能解决写覆盖问题
u011165216 2014-06-20
  • 打赏
  • 举报
回复
引用 1 楼 x_wy46 的回复:
你存储过程一半一半地执行,报变量未定义的错事必须的了 你目的是啥?想更新数据,又怕已经被更新过了,那你就主动的加锁, 在事物2中的select @t1=t from tc with(rowlock) where cno = 0002在查询的时候就锁定这条记录
我会用加锁来解决. 现在我是想用时间戳来解决写覆盖问题(即丢失更新). 或者除了用加锁的方法,还有没有其他方法在Read Committed级别下能解决写覆盖问题
专注or全面 2014-06-20
  • 打赏
  • 举报
回复
你存储过程一半一半地执行,报变量未定义的错事必须的了 你目的是啥?想更新数据,又怕已经被更新过了,那你就主动的加锁, 在事物2中的select @t1=t from tc with(rowlock) where cno = 0002在查询的时候就锁定这条记录

22,209

社区成员

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

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