根據微軟的說法,由於記憶體資料庫使用了開放式並行存取控制 ,所以事務不需要鎖來鎖定資源保證一致性。微軟認為在記憶體資料庫的事務中衝突和失敗是非常少的情況,所以假定所有的並行事務都是成功的。因此寫不會阻塞讀,寫也不阻塞寫。
下面是原文:Transactionsin Memory-Optimized Tables
Instead, transactions proceedunder the (optimistic) assumption that there will be no conflicts with othertransactions.Not usinglocks and latches and not waiting for other transactions to finishprocessing the same rows improves performance.
In addition, if a transactionreads rows that other transactions have finished processing and are in theprocess of committing, it will optimistically assume the transactions commit,rather than wait for the commit to occur. Transactions on memory-optimizedtables will take a commit dependency on these other transactions
這裡我做了一個測試:
--Create OLTP Memroy database
CREATE DATABASE imoltp ON
PRIMARY(NAME= [imoltp_data],
FILENAME='c:\data\imoltp_mod1.mdf', size=100MB)
FILEGROUP [imoltp_mod]CONTAINSMEMORY_OPTIMIZED_DATA(--name of the memory-optimized filegroup
NAME =[imoltp_dir],-- logical name of a memory-optimizedfilegroup container
FILENAME='c:\data\imoltp_dir')-- physical path to thecontainer
,(NAME= [imoltp_dir2],-- logical name of the 2nd memory-optimized filegroupcontainer
FILENAME='c:\data\imoltp_dir2')-- physical path to thecontainer
LOG ON(name = [imoltp_log],Filename='C:\DATA\imoltp_log.ldf',size=100MB)
GO
--Create OLTP Memroy table
CREATE TABLE dbo.Table1(
Id_tb1 intnotnullprimarykeynonclusteredhashwith (bucket_count=20480),
Int_Valintnotnullindex ix_Int_Valnonclusteredhashwith (bucket_count=10240),
CreateDate datetime2notnull,
[Description] varchar(255)
)
WITH (MEMORY_OPTIMIZED=ON)
GO
--insert data and query lock info
BEGIN TRAN
INSERT dbo.Table1 VALUES (1,427,getdate(),'Insert transaction')
SELECT*FROM sys.dm_tran_locks WHERErequest_session_id =@@SPID
SELECT* FROM sys.dm_db_xtp_transactions
COMMIT TRAN
情境1:session1更新資料在session2查詢
---session 1 update not commit
BEGIN TRAN
UPDATE dbo.Table1 WITH (SNAPSHOT)
SET [Description] ='Updatedtransaction'
WHERE Id_tb1 = 1
SELECT * FROM sys.dm_tran_locks WHERE request_session_id =@@SPID
SELECT * FROM sys.dm_db_xtp_transactions
--Session 2 query information, noblocking
SELECT * FROM dbo.Table1 WHERE Id_tb1 = 1
Session1的lock資訊如下,可以看到沒有表或者Page之類的Lock,只有Schema和Database Lock.
650) this.width=650;" title="2013-12-03 9-17-12.png" style="float:none;" src="http://www.bkjia.com/uploads/allimg/131229/2221495262-0.png" alt="103104837.png" />
Session2可以正常查詢到更新之前的資料,沒有阻塞
650) this.width=650;" title="1.png" style="float:none;" src="http://www.bkjia.com/uploads/allimg/131229/2221491c4-1.png" alt="103102323.png" />
情境2:
---Session 1 update not commit
BEGIN TRAN
UPDATE dbo.Table1 WITH (SNAPSHOT)
SET [Description] ='Inserttransaction'
WHERE Id_tb1 = 1
SELECT* FROM sys.dm_tran_locks WHERE request_session_id =@@SPID
SELECT* FROM sys.dm_db_xtp_transactions
---Session 2 update the same row
BEGINTRAN
UPDATE dbo.Table1 WITH (SNAPSHOT)
SET [Description] ='Inserttransaction'
WHERE Id_tb1 = 1
---Session 3 delete row
BEGINTRAN
DELETE dbo.Table1 WITH (SNAPSHOT)
WHERE Id_tb1 = 1
Session2和session3 直接報錯,沒有等待時間。錯誤如下:
Msg 41302, Level 16, State 110, Line 15
The current transaction attempted to update a record that has been updatedsince this transaction started. The transaction was aborted.
Msg 3998, Level 16, State 1, Line 12
Uncommittable transaction is detected at the end of the batch. Thetransaction is rolled back.
The statement has been terminated.
這跟普通的資料庫是不一樣的,在普通資料庫中由於session1鎖定資源,所以session2和session3都會被block. 所以針對於前面的情況需要有重試機制:
Guidelinesfor Retry Logic for Transactions on Memory-Optimized Tables
OLTP資料庫如何做衝突檢測可以參考:Transactionsin Memory-Optimized Tables
因為2014資料庫研究的還不是太多,自己的理解可能有問題,歡迎大家指正。
本文出自 “關注SQL Server技術” 部落格,請務必保留此出處http://lzf328.blog.51cto.com/1196996/1335258