Database level lock

You can use a query with UPDLOCK first, to protect you from everything throughout the transaction (except dirty reads).

It can't ever be a single lock because a single lock can't span objects. But I still believe this accomplishes what you're after, as long as you don't have queries with NOLOCK (and if you do, you're getting exactly what you asked for!).

BEGIN TRANSACTION;

SELECT pkcol FROM dbo.foo WITH (UPDLOCK, HOLDLOCK)
UNION ALL
SELECT pkcol FROM dbo.bar WITH (UPDLOCK, HOLDLOCK);

-- do other stuff

UPDATE dbo.foo SET ...;
UPDATE dbo.bar SET ...;

-- do other stuff

-- default isolation level users will be blocked until:
COMMIT TRANSACTION;

It's possible that with NOLOCK a user could sneak in in the middle and query from the two tables and get data from the first table after its update and the second table before its update. But again, that is what you get when you allow NOLOCK.

And it is also possible that at that some point a user under default isolation level could query bar and see the old value, but they'd block on foo.


I'll begrudgingly jump on the lock bandwagon.

Were you to want to actually lock the database for your update, as your title says, you could put the database in single user mode and rest assured that only your connection could connect at all while you made updates:

ALTER DATABASE AdventureWorks2012
SET SINGLE_USER
GO

And after your updates:

ALTER DATABASE whatever
SET MULTI_USER
GO

Be warned, however, that this can be tricky - for example SSMS routinely opens many connections so it will start to behave poorly in those mode. Your best bet is using sqlcmd in this mode.