Discussion:
Blocked process
(too old to reply)
simon
2012-01-06 11:34:17 UTC
Permalink
I have problems with blocked processes.

I have fact table, which is calculated (dropped and recreated) every
time, user clicks some button.
Calculation takes about 1 second.

So, if user clicks on button, the following happened:

DECLARE @result INT
BEGIN TRANSACTION
EXEC @result = sp_getapplock @Resource = 'Fact', @LockMode =
'Exclusive';

--here I check if more users clicks on this button at the same time
--if so, only first user recalculate fact table(execute calculateFact
table), others waits on result

if @result=0
BEGIN
EXEC dbo.p_calculateFact
EXEC @result = sp_releaseapplock @Resource = 'Fact';
END

COMMIT TRANSACTION

SELECT ...... FROM dbo.tblFact WHERE ....


In procedure dbo.p_recalculateFact I do the following:

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE xtype='U' AND
NAME='fact_tmp')
DROP TABLE rdr.fact_tmp

SELECT col1, col2, ..... INTO rdr.fact_tmp
FROM tbl1 JOIN tbl2 JOIN tbl3 ......
WHERE ................

--I'm using drop and select into some fact_tmp table to achieve
minimal logging
--and also while fact_tmp is calculating all users from other
processes can do the reading from tblFact table

When fact_tmp is created, I drop fact table:

IF EXISTS(SELECT * FROM dbo.sysobjects WHERE xtype='U' AND
NAME='tblFact')
DROP TABLE rdr.tblFact

Than I rename tmp table to fact table:

DECLARE @sql NVARCHAR(100)
SET @sql=N'sp_RENAME ''rdr.fact_tmp'' , ''tblFact'''

EXEC(@sql)

When I test this button with many clicks, everything works. But when
on production I get blocked processes every day on peak-times.
What should I change here? Or any suggestion how to remove blocked
processes?
I have also READ_COMMITTED_SNAPSHOT ON in this database to reduce
locks. Database is SQL2008.

br, Simon
Erland Sommarskog
2012-01-06 14:05:34 UTC
Permalink
Post by simon
When I test this button with many clicks, everything works. But when
on production I get blocked processes every day on peak-times.
What should I change here? Or any suggestion how to remove blocked
processes?
I have also READ_COMMITTED_SNAPSHOT ON in this database to reduce
locks. Database is SQL2008.
What are the blocked processes waiting on? The first step when analysing
problems of this kind is to get more facts.

READ_COMMITTED_SNAPSHOT will not help when you drop and rename tables,
because you get SCH-M locks.

You can simplify things a bit, though. Instead of dropping and renaming
tables, keep two permanent tables. One table is empty. You fill it up.
Note that INSERT can be minimally logged in SQL 2008. Then use ALTER TABLE
SWITCH to swap the tables. Truncate the old fact table. This reduces the
amount of SCH-M locks you need (but I don't know if that is your problem).
--
Erland Sommarskog, SQL Server MVP, ***@sommarskog.se

Links for SQL Server Books Online:
SQL 2008: http://msdn.microsoft.com/en-us/sqlserver/cc514207.aspx
SQL 2005: http://msdn.microsoft.com/en-us/sqlserver/bb895970.aspx
simon
2012-02-14 09:53:07 UTC
Permalink
Post by Erland Sommarskog
Post by simon
When I test this button with many clicks, everything works. But when
on production I get blocked processes every day on peak-times.
What should I change here? Or any suggestion how to remove blocked
processes?
I have also READ_COMMITTED_SNAPSHOT ON in this database to reduce
locks. Database is SQL2008.
What are the blocked processes waiting on? The first step when analysing
problems of this kind is to get more facts.
READ_COMMITTED_SNAPSHOT will not help when you drop and rename tables,
because you get SCH-M locks.
You can simplify things a bit, though. Instead of dropping and renaming
tables, keep two permanent tables. One table is empty. You fill it up.
Note that INSERT can be minimally logged in SQL 2008. Then use ALTER TABLE
SWITCH to swap the tables. Truncate the old fact table. This reduces the
amount of SCH-M locks you need (but I don't know if that is your problem).
--
SQL 2008:http://msdn.microsoft.com/en-us/sqlserver/cc514207.aspx
SQL 2005:http://msdn.microsoft.com/en-us/sqlserver/bb895970.aspx
Hi Erland,

swap the tables you mean with table partitioning, which works only on
enterprise edition of SQL server?
I have enterprise version in this case but anyway, what about this
scenario:

INSERT INTO rdr.fact_tmp
SELECT * ...

DECLARE @rdrLock BIT
SELECT @rdrLock = 1 WHERE EXISTS (SELECT 1 FROM rdr.fact WITH
(TABLOCKX))

EXEC sp_rename 'rdr.fact', 'temp'
EXEC sp_rename 'rdr.fact_tmp', 'fact'
EXEC sp_rename 'rdr.temp', 'fact_tmp'

TRUNCATE TABLE rdr.fact_tmp

The problem is that everything is in transaction and with drop table
and insert into table I get locks on sys.objects when I have many
users and everything stop working.

Thanks,
Simon
Erland Sommarskog
2012-02-14 22:38:04 UTC
Permalink
Post by simon
swap the tables you mean with table partitioning, which works only on
enterprise edition of SQL server?
No, I mean ALTER TABLE SWITCH which works in all editions of SQL Server.
The raison d'ĂȘtre for this command is indeed switching in partitioned
tables, but you can use it to flip two unpartitioned tables.
Post by simon
The problem is that everything is in transaction and with drop table
and insert into table I get locks on sys.objects when I have many
users and everything stop working.
Even with switching there is a locking issue: to do the switch you need
a Sch-M lock, and if there are long-running queries all the time, you
will be starved. (And snapshot or NOLOCK will not help you here.)
--
Erland Sommarskog, SQL Server MVP, ***@sommarskog.se

Links for SQL Server Books Online:
SQL 2008: http://msdn.microsoft.com/en-us/sqlserver/cc514207.aspx
SQL 2005: http://msdn.microsoft.com/en-us/sqlserver/bb895970.aspx
Loading...