【新手问题】如何防止同时执行同一个存储过程?

songjinxi123 2012-08-22 03:50:48
因为我的数据库有个表,每条数据不同,在用户读取一条数据之后,就会删除这条数据,并且把这条数据存在另外一个表里。我把这3个操作写在了同一个存储过程当中,我担心用户多了,就会出现两个用户同时执行这个存储过程,这样有可能就读取到相同的数据。请问如何避免这个问题?

只要能实现相同的功能,并且避免读到相同的数据,任何方法都可以。当然越简单越好。
...全文
362 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhangyangziwo 2012-08-23
  • 打赏
  • 举报
回复
@@error和@@ROWCOUNT,2000上都有。
看看联机丛书,上边有这两个系统函数搭配使用的例子。

D. 与 @@ROWCOUNT 一同使用 @@ERROR
下面的示例用 @@ERROR 和 @@ROWCOUNT 验证一条 UPDATE 语句的操作。为任何可能出现的错误而检验 @@ERROR 的值,而用 @@ROWCOUNT 保证更新已成功应用于表中的某行。

USE pubs
GO
CREATE PROCEDURE change_publisher
@title_id tid,
@new_pub_id char(4)
AS

-- Declare variables used in error checking.
DECLARE @error_var int, @rowcount_var int

-- Execute the UPDATE statement.
UPDATE titles SET pub_id = @new_pub_id
WHERE title_id = @title_id

-- Save the @@ERROR and @@ROWCOUNT values in local
-- variables before they are cleared.
SELECT @error_var = @@ERROR, @rowcount_var = @@ROWCOUNT

-- Check for errors. If an invalid @new_pub_id was specified
-- the UPDATE statement returns a foreign-key violation error #547.
IF @error_var <> 0
BEGIN
IF @error_var = 547
BEGIN
PRINT "ERROR: Invalid ID specified for new publisher"
RETURN(1)
END
ELSE
BEGIN
PRINT "ERROR: Unhandled error occurred"
RETURN(2)
END
END

-- Check the rowcount. @rowcount_var is set to 0
-- if an invalid @title_id was specified.
IF @rowcount_var = 0
BEGIN
PRINT "Warning: The title_id specified is not valid"
RETURN(1)
END
ELSE
BEGIN
PRINT "The book has been updated with the new publisher"
RETURN(0)
END
GO

Viccy_Yao 2012-08-22
  • 打赏
  • 举报
回复
判断事务返回行,若返回行不是得到的值,就回滚.
發糞塗牆 2012-08-22
  • 打赏
  • 举报
回复
@@Error这个好像也是2000以后才有,对于楼主的问题,最好还是使用事务。把你的代码放到:

begin tran
代码
if @@rowcount(可能2000也没有,如果没有,你可以使用select count(1) from 表来判断是否插入或者更新成功)>0 --代表改动成功
commit
else --改动不成功
rollback

不过还是建议楼主自己看看2000的联机丛书中关于事务的那部分,用久了2008,不知道2000有啥函数了。
但是解决你这个问题的方法一般就是使用事务了。
songjinxi123 2012-08-22
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

使用事务
SQL code

BEGIN TRANSACTION
INSERT INTO ...
--你的语句 SAVE TRANSACTION savepoint(根据你的情况可以设置保存点)
IF @@Error<>0
BEGIN
PRINT '不能重复插入'
ROLLBACK TRANSACTION--事务回滚语句
END
ELSE
BEGIN
PRINT '插入成功'
COMMI……
[/Quote]

请问@@Error这个是内置的变量吗?
zhiming2076 2012-08-22
  • 打赏
  • 举报
回复
给你那张表加个字段,UserID
不管谁进来,就只能操作他那个UserID标识的那些记录就行了
zhangyangziwo 2012-08-22
  • 打赏
  • 举报
回复
读取记录,删除记录,将记录插入其他表,这三步操作是应该作为一个事务的,整体提交,整体回滚。
但是事务,避免不了读取相同的数据,你应该判断删除记录这步操作的执行结果和影响的行数,即@@error和@@ROWCOUNT,就算执行成功,但是影响的行数是0的话,也回滚事务,这样就避免重复啦。
以学习为目的 2012-08-22
  • 打赏
  • 举报
回复
使用事务

BEGIN TRANSACTION
INSERT INTO ...
--你的语句 SAVE TRANSACTION savepoint(根据你的情况可以设置保存点)
IF @@Error<>0
BEGIN
PRINT '不能重复插入'
ROLLBACK TRANSACTION--事务回滚语句
END
ELSE
BEGIN
PRINT '插入成功'
COMMIT TRANSACTION--事务提交语句
END
END
songjinxi123 2012-08-22
  • 打赏
  • 举报
回复
对了,我是说的SQL 2000 。貌似没有
begin try 这个东西。
gw6328 2012-08-22
  • 打赏
  • 举报
回复
你可以在msdn上搜一下事务相关的
写法
一般的
begin tran
begin try
insert ...
update ...
--这里就是你写的语句
commit tran
end try
bgein catch
rollback tran
end catch
songjinxi123 2012-08-22
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

你可以把这个写成一个事务。
也可以在上层代码里控制,只能一个调用。
[/Quote]

能说具体点吗?事务怎么写?
gw6328 2012-08-22
  • 打赏
  • 举报
回复
你可以把这个写成一个事务。
也可以在上层代码里控制,只能一个调用。

34,594

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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