一个简单的存储过程产生死锁

lengue 2009-05-27 04:08:22
加精
由于系统从Oracle数据库迁移成MsSQL,数据表的主键由程序控制产生,不想过多的改程序,于是我把所有表的主键保存在一个数据表里,表结构很简单:
create table my_seq(
sequence_name varchar(50) not null,
sequence_value int(4)
)


自定义存储过程如下:

SQL code
CREATE PROCEDURE GET_NEXTVAL

@sequence_name varchar(200),
@sequence_value INT output

AS
BEGIN
-- DECLARE @sequence_value INT;
SET NOCOUNT ON
set @sequence_value = -1;

begin TRANSACTION
update my_seq
SET sequence_value=sequence_value+1
WHERE sequence_name=@sequence_name ;
select @sequence_value=sequence_value from my_seq WHERE sequence_name=@sequence_name ;
COMMIT TRANSACTION

SET NOCOUNT OFF

RETURN @sequence_value
END
GO




存储过程做的事主要是:把键值加1后,马上更新数据库里的数据,最后返回处理后的下一数值.

应用系统运行一段时间会出现如下异常:
org.springframework.jdbc.UncategorizedSQLException: CallableStatementCallback; uncategorized SQLException for SQL [{call dbo.GET_NEXTVAL(?, ?)}]; SQL state [40001]; error code [1205]; [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]事务(进程 ID 58)与另一个进程已被死锁在 lock 资源上,且该事务已被选作死锁牺牲品。请重新运行该事务。; nested exception is java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]事务(进程 ID 58)与另一个进程已被死锁在 lock 资源上,且该事务已被选作死锁牺牲品。请重新运行该事务。
java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]事务(进程 ID 58)与另一个进程已被死锁在 lock 资源上,且该事务已被选作死锁牺牲品。请重新运行该事务。


网络上找到很多类似这样的问题,但我还是没有找到解决的办法.
...全文
1235 42 打赏 收藏 转发到动态 举报
写回复
用AI写文章
42 条回复
切换为时间正序
请发表友善的回复…
发表回复
netbigstrong 2011-05-05
  • 打赏
  • 举报
回复
学习了,用加索引的方法解决了问题, 非常感谢 Garnett_KG
hu320 2010-09-09
  • 打赏
  • 举报
回复
学习了
zhqibin 2009-06-25
  • 打赏
  • 举报
回复
Up 学习!!
lengue 2009-06-01
  • 打赏
  • 举报
回复
发现一个很低级的问题,我用工具把数据库从Oracle迁移到MsSQL的,重新检查了下发现MsSQL上的主键唯一约束有的没有生成.加上后,再没有发现那个异常了.
flairsky 2009-05-31
  • 打赏
  • 举报
回复
这么简单的过程也能死锁?不用强制什么锁吧
lengue 2009-05-31
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 Logson 的回复:]
这是一个并发性的问题,不应该仅仅从解决死锁这个角度考虑,否则即便暂时解决了死锁,可能也会出现其他的比如数据错误
我认为如果是应该再调用这个过程的代码加控制,每一个时刻保证对一个表(sequence_name ),只能有一个进程访问,不通表才能同时访问
或者对每个事务设置优先级,不过性能可能不如前者了
[/Quote]

我给方法加同步(synchronized)了也没用,还是报同样的异常.
觅食的猫猫 2009-05-31
  • 打赏
  • 举报
回复
答题的还没1/3呢.20多个都是顶的....嗨....
水上海 2009-05-31
  • 打赏
  • 举报
回复
up
wjlsmail 2009-05-31
  • 打赏
  • 举报
回复
Mark
clop 2009-05-31
  • 打赏
  • 举报
回复
可以提高一下效率
update my_seq
SET @sequence_value = sequence_value+1,sequence_value=sequence_value+1
WHERE sequence_name=@sequence_name ;

产生锁的话,显然是你运行此存储过程太频繁了,有些程序不是你想不要多改就能不改的
当然的设计显然是自己在制造瓶颈!
xcj0722 2009-05-30
  • 打赏
  • 举报
回复
xue xi ing
Ny-6000 2009-05-30
  • 打赏
  • 举报
回复
不为得分。
lovezx1028 2009-05-30
  • 打赏
  • 举报
回复
guan zhu yi xia ..
wanghui87 2009-05-29
  • 打赏
  • 举报
回复
主要是学习
i118223 2009-05-29
  • 打赏
  • 举报
回复
先试下arrow_gx的方法,不过"select 使用 nolock"我担心会读脏数据.
ch315537 2009-05-29
  • 打赏
  • 举报
回复
主要是蹭分
gentlebrother 2009-05-28
  • 打赏
  • 举报
回复
mark
Logson 2009-05-28
  • 打赏
  • 举报
回复
这是一个并发性的问题,不应该仅仅从解决死锁这个角度考虑,否则即便暂时解决了死锁,可能也会出现其他的比如数据错误
我认为如果是应该再调用这个过程的代码加控制,每一个时刻保证对一个表(sequence_name ),只能有一个进程访问,不通表才能同时访问
或者对每个事务设置优先级,不过性能可能不如前者了
wsq279024988 2009-05-28
  • 打赏
  • 举报
回复
学习一下啊
烈火蜓蜻 2009-05-28
  • 打赏
  • 举报
回复
回帖是一种美德!每天回帖即可获得 10 分可用分
加载更多回复(20)

27,579

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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