[英]Advice for methods handling T-SQL transactions (ADO)?
我們在這里討論的是隔離級別,即與本地運行的 Express MSSQL 服務器相關的並發性。
當用戶決定編輯 GridView 中的一行時,我試圖找出一種方法來啟動數據鎖定 - >保持數據鎖定直到他/她停止編輯(IE按下“更新”)。
作為事件列表,它看起來像這樣:
我已經開始制作一些方法。
在這些方法之前,我的服務方法始終將連接保存在私有/局部變量中:
private SqlConnection connection = new SqlConnection("Data Source=host\\SQLEXPRESS;Initial Catalog=tablename;User ID=sa;Password=password");
然后是方法。
public SqlTransaction BeginTransaction() {
//Something like this
SqlTransaction transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted);
return transaction;
}
public bool UpdateTidsregistrering(some parameters to be parsed from GUI) {
using(connection) {
connection.Open();
SqlCommand command = connection.CreateCommand();
//Execute a query here with a try-catch around like normally...
}
}
public void CloseTransaction() {
//Close transaction and connection?
}
我的大問題是:這可以正確利用嗎?
需要考慮的場景...
- 有人開始編輯一行,然后晚上回家
- 許多不同的用戶持有許多不同行的未結交易
- 用戶編輯時網絡連接斷開
- 用戶 A 刷新屏幕,用戶 B 修改並提交一行,用戶 A 開始修改該行,忽略用戶 B 的更改
- 在多行上持有多個未結交易的成本
- 所有用戶必須永久打開連接的成本
一般來說,我的偏好是只在代碼周圍使用 TRANSACTIONS 而沒有任何暫停。 尤其是暫停創造了任何人際互動。
對於這種情況,我首選的 model 是使用“最后修改”時間戳。
在 SQL 中,你想要的是:
begin transaction;
select id
from tablename with (updlock, rowlock, holdlock, readpast)
where id = @id;
if @@rowcount = 0
begin
raiseerror('This record does not exists or is currently locked.',16,1);
rollback tran;
end;
用戶在此處進行編輯...
update tablename ... ;
commit transaction;
您可以使用 c# 方法輕松地將其包裝到 LockRecord/UnlockRecord。
請注意,您將需要id
上的唯一索引,否則會發生不好的事情。
不要為此持有交易。 它將要求您:
用戶可以在多長時間內編輯記錄? 如果用戶鎖定記錄並去吃午飯會發生什么? 用戶不應持有連接,並且交易應盡可能短。 整個單獨的部分是我們正在談論 ASP.NET ,您必須將連接存儲在 session 中,如果用戶不提交更改,則連接將泄漏 - 您很快就會失去連接。
這整個可以被認為是完全糟糕的設計,你不應該做的事情!
將新列添加到您的表中: LockedBy
(您也可以添加LockedAt
)。 僅當用戶想要編輯記錄時才更改事務中的這些列。 填寫這些列后,其他用戶將無法將記錄切換到編輯模式。 一旦用戶提交更改,就會清除這些列。
您將遇到一個問題 - 如果用戶取消更改,您必須解鎖記錄但如果用戶只是關閉他的瀏覽器怎么辦? 這將需要一些定期運行並解鎖長時間鎖定的記錄的工作(第二列的原因)。 您可以在 SQL 代理中運行此類作業。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.