March 15, 2005 at 5:44 am
Hi,
I have written the following StoredProcedure
create Procedure spCreateQuestion(
@QuestionName varchar(30)
)
as
SET NOCOUNT ON
declare @newAnswerId int
declare @newQuestionId int
set @QuestionName='New Question'
BEGIN TRANSACTION Q1
--Creates New QuestionId with AnswerId 0
INSERT INTO Questions(QuestionId,Name,AnswerId)
SELECT 1 + COALESCE(MAX(QuestionId), 0),RTRIM(@QuestionName),0
FROM Questions
--QuestionId just now created
SELECT @newQuestionId=QuestionId FROM Questions WHERE Name=@QuestionName
BEGIN TRANSACTION QA1
--Create an AnswerId
INSERT INTO Answers(AnswerId)
SELECT 1 + COALESCE(MAX(AnswerId), 0)
FROM Answers
--AnswerId just now created(I hope not the best way to do like this)
SELECT @newAnswerId=MAX(AnswerId) from Answers --is it the best way to call statement like this or any other way better than this
--update Questions Table with this new Answerid
UPDATE Questions
set
where QuestionId=@newQuestionId
COMMIT TRANSACTION QA1
COMMIT TRANSACTION Q1
I think the second Transaction is not locking the table..
Can some one please have a look at it and suggest me how do we go about it..
I can't Create the tables with identity property for id columns.
thanks
March 15, 2005 at 6:25 am
you may want to check out IDENTITY and scope_identity if you can live with gaps in your numberings. overlooked the last part of your question.
An alternative is having a parameter-table and proc set to manage sequences.
I hope you have provided propre indexing ?
Normaly , nested transaction don't lock eachother !
Johan
Learn to play, play to learn !
Dont drive faster than your guardian angel can fly ...
but keeping both feet on the ground wont get you anywhere :w00t:
- How to post Performance Problems
- How to post data/code to get the best help[/url]
- How to prevent a sore throat after hours of presenting ppt
press F1 for solution, press shift+F1 for urgent solution 😀
Need a bit of Powershell? How about this
Who am I ? Sometimes this is me but most of the time this is me
March 15, 2005 at 6:49 am
Thanks alzdba,
I learned one point that nested transactions don't lock each other..but i see people starting different transactions and committing in different places..
coming to my query i used the following statement to get the last created sequence.Will it gives me the correct sequenceId(i mean last created id)
SELECT @newAnswerId=MAX(AnswerId) from Answers
i did not follow you on this statement
parameter-table and proc set to manage sequences
you mean to create temp table for this..
thanks
March 15, 2005 at 7:04 am
... parameter-table and proc set to manage sequences ...
This way you could emulate identity
This is just a simple representation :
create table t_mySequenceParameters (
TableName varchar(128) not null primary key
, ParameterValue int not null default 0
)
create proc spcPicNewSequence
@TableName varchar(128)
, @NewSequence int OUTPUT
as
begin
set nocount on
declare @error int
declare @rowcount int
begin tran
update t_mySequenceParameters
set ParameterValue = ParameterValue + 1
where TableName = @TableName
select @error = @@error , @rowcount = @@rowcount
if @error = 0
begin
if @rowcount = 1
begin
select @NewSequence = ParameterValue
from t_mySequenceParameters
where TableName = @TableName
end
end
return 0
commit tran
else
begin
rollback tran
return (@error)
end
This way, you may want to execute the spc in its own transaction, otherwize, you will endup with locking anyway.
Johan
Learn to play, play to learn !
Dont drive faster than your guardian angel can fly ...
but keeping both feet on the ground wont get you anywhere :w00t:
- How to post Performance Problems
- How to post data/code to get the best help[/url]
- How to prevent a sore throat after hours of presenting ppt
press F1 for solution, press shift+F1 for urgent solution 😀
Need a bit of Powershell? How about this
Who am I ? Sometimes this is me but most of the time this is me
March 15, 2005 at 7:19 am
How about this
create Procedure spCreateQuestion(@QuestionName varchar(30))
as
SET NOCOUNT ON
declare @newAnswerId int
declare @newQuestionId int
-- Start Transaction to lock rows
BEGIN TRANSACTION
-- Insert row into Questions and Answers tables with zero ID's
-- This will prevent anyone else from doing this
INSERT INTO Questions (QuestionId,[Name],AnswerId)
VALUES (0,RTRIM(@QuestionName),0)
INSERT INTO Answers(AnswerId) VALUES (0)
-- Get Next AnswerId
SELECT @newAnswerId = ISNULL(MAX(AnswerId),0)+1
FROM Answers
-- Update Answers table with new ID
UPDATE Answers
SET AnswerId = @newAnswerId
WHERE AnswerId = 0
-- Get Next QuestionId
SELECT @newQuestionId = ISNULL(MAX(QuestionId),0)+1
FROM Questions
-- Update Questions table with new ID and AnswerID
UPDATE Questions
SET QuestionId = @newQuestionId,
AnswerID = @newAnswerId
WHERE QuestionId = 0
-- Release Transaction and locks
COMMIT TRANSACTION
Far away is close at hand in the images of elsewhere.
Anon.
March 15, 2005 at 7:25 am
thanks for the procedure alzdba,
But from where you are getting the ParameterValue
March 15, 2005 at 7:43 am
Thanks David,
never thought about this way..
But when i executed your procedure it is holding the lock for one table only..
I have tested this in Query analyzer removing the COMMIT TRANSACTION statement and went back to my EnterPrise manager and tried to run the data in my table but it has locked only one table .
what am i missing there..
March 15, 2005 at 8:41 am
I had no problems testing this in QA and both my tables were locked.
Did you use just the tsql, you cannot have a procedure with a begin tran without corresponding commit/rollback.
Far away is close at hand in the images of elsewhere.
Anon.
March 15, 2005 at 8:52 am
i did tested this in my QA using Tsql, for some reason it is locking only the Questions table
but not Answers
Is there anything to do with indexes or primary keys on those table as i have no
primary key in both the table.Just created index on both of them.
March 15, 2005 at 9:11 am
When I tested the code, my tables did not have primary keys or indexes and EM was locked out of both tables and EM showed the tables as locked under Locks / process ID in the Object column.
The only thing about transactions are they are for a connection so you must have separate connections to get the locking to work.
Far away is close at hand in the images of elsewhere.
Anon.
March 15, 2005 at 9:32 am
David,thanks for taking time to solve my problem..
What i did not understand is i have run the query in two Query analyzers.
I executed my query in first QA and it holded the lock correctly and did not allowed to execute from Second QA.But this is not the same when i tried to access data through EnterPrise Manager.Enterprise manager holds the lock for only one table.
And also why will my original SP will fail to lock the table
I think this is also doing the same..
create Procedure spCreateQuestion(
@QuestionName varchar(30)
)
as
SET NOCOUNT ON
declare @newAnswerId int
declare @newQuestionId int
set @QuestionName='New Question'
BEGIN TRANSACTION
--Creates New QuestionId with AnswerId 0
INSERT INTO Questions(QuestionId,Name,AnswerId)
SELECT 1 + COALESCE(MAX(QuestionId), 0),RTRIM(@QuestionName),0
FROM Questions
--QuestionId just now created
SELECT @newQuestionId=QuestionId FROM Questions WHERE Name=@QuestionName
--Create an AnswerId
INSERT INTO Answers(AnswerId)
SELECT 1 + COALESCE(MAX(AnswerId), 0)
FROM Answers
--AnswerId just now created(I hope not the best way to do like this)
SELECT @newAnswerId=MAX(AnswerId) from Answers --is it the best way to call statement like this or any other way better than this
--update Questions Table with this new Answerid
UPDATE Questions
set
where QuestionId=@newQuestionId
COMMIT TRANSACTION
March 15, 2005 at 10:18 am
Well thats EM for you
Yes your's should do the same, however, I wonder if there is a (very) small chance that two processes could generate the same id, assuming that sql will have to do the select to get the id and then do the insert, I don't know if it is all done in one go or not, maybe profiler would tell you.
alzdba's solution of using a control record to keep count of ID's is one way to overcome this. I use this method, albeit in a different form, for non IDENTITY ID columns that I want to control.
Far away is close at hand in the images of elsewhere.
Anon.
Viewing 12 posts - 1 through 11 (of 11 total)
You must be logged in to reply to this topic. Login to reply