以下存储过程代码是否适用于多用户应用程序。它工作正常。我想知道是否有更好的方法可以做到这一点以及是否有任何性能问题。
proc有三个sql语句,如1.在分配表2中更新硬件状态。计算下一个适当的主键值,以便在DEFECT_LOG表中插入新记录.3。将值插入DEFECT_LOG表。如果交易成功,我也使用变量返回1。
ALTER PROCEDURE spCreateDefective
(
@alloc_ID nvarchar(50),
@cur_date datetime,
@problem_desc nvarchar(MAX),
@got_defect_date datetime,
@trans_status tinyint OUTPUT --Used to check transaction status
)
AS
/* Transaction Maintainer Statements */
BEGIN TRAN transac1
SET XACT_ABORT ON
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
/* Declaration Area */
DECLARE @temp nvarchar(10)
DECLARE @def_ID nvarchar(20)
/* Updating Inventory Status to 'Defective' and Updating Release Date to current System date */
UPDATE INV_Allocation_DB
SET INV_STATUS = 'Defective' , RELEASE_DATE=@cur_date
WHERE INV_ID=@alloc_ID
/* Calculates New Primary Key for the DEFECT_LOG Table */
-- Returns the largest number or 1 if no records are present in the table
SELECT @temp=COALESCE(CONVERT(int,SUBSTRING(MAX(DEFECT_ID),5,5))+1,1) FROM DEFECT_LOG
SET @def_ID = 'DEF_'+ RIGHT(replicate('0',5)+ convert(varchar(5),@temp),5)
/* Insert statement for inserting data into DEFECT_LOG */
INSERT INTO DEFECT_LOG (DEFECT_ID,INV_ID,PROB_DESC,GOT_DEFECT_DATE)
VALUES(@def_ID,@alloc_ID,@problem_desc,@got_defect_date)
SET @trans_status = 1
COMMIT TRAN transac1
/* Returns 1 if transaction successful */
RETURN @trans_status
答案 0 :(得分:2)
建议不要使用SERIALIZABLE事务级别,除非您必须拥有一个。这会增加阻塞和降低吞吐量的可能性。
您似乎正在使用它以保证唯一的DEFECT_ID?为什么不使用IDENTITY列代替DEFECT_ID?
答案 1 :(得分:1)
我个人会使用IDENTITY字段作为真正的主键,但是后面还有一个带有字母数字标识符的附加列。 (可能是一个持久的计算字段)
这应该减少有关并发的问题数量。
答案 2 :(得分:0)
因为iam从表中读取当前最大的主键值,所以不需要序列化操作,以免发生读取错误;如果有人在两个阶段之间的时间内在defect_log表中插入新记录1.获取最大主键值并且2.插入defect_log表?