Showing posts with label causing. Show all posts
Showing posts with label causing. Show all posts

Friday, March 30, 2012

Inserted row deletes after trigger

I'm hoping someone has seen this before because I have no idea what could be causing it.

I have an SQL 2005 database with multiple tables and several triggers on the various tables all set to run after insert and update.

My program inserts a record into the "items" via a SP that returns the index of the newly added row. The program then inserts a row into another table that is related to items. When the row is inserted into the second table it gets an error that it cannot insert the record because of a foreign key restraint. Checking the items table shows the record that was just inserted in there is now deleted.

The items record is only deleted when I have my trigger on that table enabled. Here is the text of the trigger:

GO
SETANSI_NULLSON
GO
SETQUOTED_IDENTIFIERON
GO

ALTERTRIGGER [dbo].[TestTrigger]
ON [dbo].[items]
AFTERINSERT

AS
BEGIN

SETNOCOUNTON;

INSERTINTO tblHistory(table_name, record_id, is_insert)
VALUES('items', 123, 1)

END

tblHistory's field types are (varchar(50), BigInt, bit).

As you can see there is nothing in the trigger to cause the items record to be deleted, so I have no idea what it could be? Anyone ever see this before?

Thanks in advance!

Hey,

I don't know that the row is deleted, but that the row doesn't get actually inserted for some reason. What do the two insertions look like? In SQL or ADO.NET code? Could it be that the first item doesn't get inserted, then returns a number that doesn't match an entry in that table, and that is why you get an error for the second insert?

|||

No, the first item is inserted and the returned value is exactly what it should be. When we test it without the trigger enabled and it all works, the new primary key value is the next value after the one that disapeared (i.e. if the record that was deleted was 5 the next one that works is 6).

|||

Are you using @.@.identity?

|||

If one of the follow on triggers fails, for whatever reason, the insert statement will be rolled back.

I suggest commenting out the triggers one by one (from last run to first run) until you figure out which one is the problem.

(Or learn to use the debugger in sql server.)

|||

David is correct in that the trigger code is considered part of the insert transaction.

If the trigger fails, then the entire "transaction" is rolled back, including the insert. If tblHistory has a foreign key constraint, and the trigger fails because of it, then you will get exactly what you are describing. The record is inserted partially (uncommitted), the trigger is fired, an error is encountered, then the insert is rolled back and the error from the trigger is sent to the client.

|||

It couldn't have been the trigger failing, b/c there are no constraints on the history table and while yo uare correct the error would have been returned as if it was coming from the insert statement I said above "When the row is inserted into the second table it gets an error that it cannot insert the record because of a foreign key restraint." The error was not about hte history table.

Motley you actually had the answer. What was happening is the stored procedure ran and inserted the row into items, the trigger ran on that and inserted the row into web updates, the stored procedure then returned the @.@.Identity, but since that returns the last identity of any insert to the database it was returning the identity of the history table, not the items table. When the second insert was run it was trying to insert the wrong identity and failed the foreign key restraint, resulting in the entire transaction to fail and rollback, giving the appearance the items record had been deleted.

Thanks for your help!

|||

Use scope_identity(), not identity! scope_identity was created to avoid just this problem!

sql

Monday, March 19, 2012

Insert statment and strange locking behavior

Hi,
We were encountering table locks in the application that is hindering the
concurrency and we found that the insert into table was causing the table
lock and I can easily reproduce this from query analyzer. The statement look
s
like following:
Insert into db1..tab1 select * from db2..tab2
Table tab1 contains about 12M rows and tab2 contains 5000 rows.
Following are the stats and observations:
There is only 1 index on tab1 that is unique clustered and is on sequence
generated columns so we don’t expect lot of page splits since all the new
data will go at the end.
There is no memory pressure on SQL Server since this is the only user
connected.
If we insert only 2999 rows then SQL Sever takes row locks and IX locks on
page and table but when we try to insert >3000 rows SQL Server escalate the
row lock to table X lock so somehow there is some SQL Server algorithm that
causes it to escalate it to table lock
In SQL Server 2005, we are not able to reproduce the issue and it only takes
row locks even for 5000 rows so it seems like the issue is fixed in new
release.
Also >3000 rows insert is not true for all table since on some table SQL
Server escalate to table locks for >2000 rows so there is some other interna
l
SQL Server algorithm.
We are just wondering if someone else sees the same kind of issue and what
the solution was.
This is from Books online
“when a transaction requests rows from a table, SQL Server automatically
acquires locks on those rows affected and places higher-level intent locks o
n
the pages and table, or index, which contain those rows. When the number of
locks held by the transaction exceeds its threshold, SQL Server attempts to
change the intent lock on the table to a stronger lock (for example, an
intent exclusive (IX) would change to an exclusive (X) lock). After acquirin
g
the stronger lock, all page and row level locks held by the transaction on
the table are released, reducing lock overhead”
It is very difficult to believe that threshold is just 5000 row locks for
this type of insert since we had seen SQL Server taking millions of row lock
s
and works fine
Thanks
--HarvinderYou do not say whether you are explicitly defining a locking method on your
query/update
NOLOCK or ROWLOCK
"harvinder" wrote:

> Hi,
> We were encountering table locks in the application that is hindering the
> concurrency and we found that the insert into table was causing the table
> lock and I can easily reproduce this from query analyzer. The statement lo
oks
> like following:
> Insert into db1..tab1 select * from db2..tab2
> Table tab1 contains about 12M rows and tab2 contains 5000 rows.

Insert statment and strange locking behavior

Hi,
We were encountering table locks in the application that is hindering the
concurrency and we found that the insert into table was causing the table
lock and I can easily reproduce this from query analyzer. The statement looks
like following:
Insert into db1..tab1 select * from db2..tab2
Table tab1 contains about 12M rows and tab2 contains 5000 rows.
Following are the stats and observations:
There is only 1 index on tab1 that is unique clustered and is on sequence
generated columns so we donâ't expect lot of page splits since all the new
data will go at the end.
There is no memory pressure on SQL Server since this is the only user
connected.
If we insert only 2999 rows then SQL Sever takes row locks and IX locks on
page and table but when we try to insert >3000 rows SQL Server escalate the
row lock to table X lock so somehow there is some SQL Server algorithm that
causes it to escalate it to table lock
In SQL Server 2005, we are not able to reproduce the issue and it only takes
row locks even for 5000 rows so it seems like the issue is fixed in new
release.
Also >3000 rows insert is not true for all table since on some table SQL
Server escalate to table locks for >2000 rows so there is some other internal
SQL Server algorithm.
We are just wondering if someone else sees the same kind of issue and what
the solution was.
This is from Books online
â'when a transaction requests rows from a table, SQL Server automatically
acquires locks on those rows affected and places higher-level intent locks on
the pages and table, or index, which contain those rows. When the number of
locks held by the transaction exceeds its threshold, SQL Server attempts to
change the intent lock on the table to a stronger lock (for example, an
intent exclusive (IX) would change to an exclusive (X) lock). After acquiring
the stronger lock, all page and row level locks held by the transaction on
the table are released, reducing lock overheadâ'
It is very difficult to believe that threshold is just 5000 row locks for
this type of insert since we had seen SQL Server taking millions of row locks
and works fine
Thanks
--HarvinderYou do not say whether you are explicitly defining a locking method on your
query/update
NOLOCK or ROWLOCK
"harvinder" wrote:
> Hi,
> We were encountering table locks in the application that is hindering the
> concurrency and we found that the insert into table was causing the table
> lock and I can easily reproduce this from query analyzer. The statement looks
> like following:
> Insert into db1..tab1 select * from db2..tab2
> Table tab1 contains about 12M rows and tab2 contains 5000 rows.