所以我们有四个陈述(为了问题的目的而改变)
它们在TransactionScope
(ReadCommitted
)内运行,多个进程可以同时调用包含这些语句的相同存储过程:
SELECT @BathroomId = B.BathroomId
FROM Bathrooms B
WHERE B.BathroomSuite = @BathroomSuite AND B.SuiteIsAvailable = 1
(No indexes used at all)
SELECT @OrderReceiptId = O.OrderReceiptId
FROM Order O
WHERE O.OrderId = @OrderId
(Clustered Index)
IF ISNULL(@OrderReceiptId, -1) = -1
BEGIN
INSERT INTO [dbo].[OrderReceipt]
.....
(Clustered index on PK)
UPDATE Order
SET OrderReceiptId = @@SCOPE_IDENTITY
WHERE OrderId = @OrderId
从我有限的阅读中,我明白只有行锁才能用于SELECTS(因此,限制了对这些表上争用的影响)
但是,那么,INSERT / UPDATE将使用哪些锁,然后这会对其他进程与总体事务进行竞争产生什么影响呢?
在交易完成之前,我们是否有效地控制这些表格?或者只是一些表(即只是INSERT和UPDATE - 由于事务实际上只与我脑中的INSERT和UPDATE相关(例如,无法回滚SELECT)
其他竞争过程是否必须等到交易完成(我认为这当然不是不合理的)
数据库锁定和事务关系有点模糊,因为这会影响包含这些语句的存储过程的多个调用者。
N.B。请忽略Order和OrderReceipt之间的狡猾关系,这绝对是次优的。
我认为我将Transaction混淆为锁定机制(有点像用于线程同步的线程锁)和数据库级锁定
编辑:是的我正在混淆交易和数据库锁定(一起使用但责任略有不同),任何谷歌101网站都告诉我这一点。这很令人尴尬,但它会教我没有先mooch。
答案 0 :(得分:0)
如果有多个进程调用相同的SP,则不存在争用或锁定,阻塞..
您的选择在您所处的隔离级别中获取共享锁定,并且只要该行读取就会释放锁定
但是你可能会看到锁定,阻止,如果有一些更新进程或删除尝试同时访问该表的进程..
你也可以使用这个traceflag to see all the locks taken ..这个跟踪标志会写出为了消息标签而采取的锁
DBCC TRACEON(1200,3604,-1);
SELECT ....
DBCC TRACEOFF(1200,3604,-1);
答案 1 :(得分:0)
如果您使用的是SQL Server,这可能取决于您的快照隔离级别。
据我所知,将内容插入到聚簇索引中会锁定整个表。换句话说,第一个插入将阻止所有其他插入,直到完成。阅读(SELECT)是一个不同的故事:
检查数据库的属性/选项,查找"是否读取已提交的快照"。如果此设置为True,则在您持有该插入事务时,并发进程可以读取。如果不是 - 在交易完成之前,所有其他读取都将被阻止。
请注意,在某些情况下启用此选项可能会影响数据库性能,但我个人并未遇到任何实际问题。