I would like to perform the following operations:
TRUNCATE TABLE Table1;
TRUNCATE TABLE Table2;
-- I do not want to allow possibly the viewing and definitely the modification
-- of Table1 or Table2 at this point, so that I can make changes to them atomically
-- possibly even regardless of the isolation level in other sessions (or this one).
-- So, I lock both tables. I want to remove any data that could have made its way into
-- the tables, due to the current isolation level, for example, and remove any rows.
-- Also, from this point on, I want the tables to be unviewable (all queries blocked)
-- and unmodifyable (all INSERTs, UPDATEs, DELETEs blocked)
DELETE FROM Table1 WITH(TABLOCKX, HOLDLOCK);
DELETE FROM Table2 WITH(TABLOCKX, HOLDLOCK);
-- This is a long running complex INSERT operation into Table1
INSERT INTO Table1... SELECT ...
-- This is a long running complex INSERT operation into Table2, based on the
-- data in Table1 and some other ancillary tables
INSERT INTO Table2... SELECT ... FROM Table1...
COMMIT;
I want to block all access to both tables Table1 and Table2 from the point that the TRUNCATE commands are complete to the point that they are completely constructed and the changes committed with the COMMIT. Preferably, even from clients using READ_UNCOMMITTED isolation level and even those performing NOLOCK queries, if this is possible.
Any advice would be appreciated.
Use partition switching. Despite the common belief, partition switching does not require your table to be partitioned. Prepare the new data in a staging table(s), the quickly switch them in and replace the old data:
See Transferring Data Efficiently by Using Partition Switching.