我有一个事务,它将大量数据(超过5000条记录)插入到3个表中(因此需要一段时间),这没关系,但我注意到了一些令人不安的事情。在此过程中,所有3个表似乎都被锁定了。
插入交易:
using(var db = new MyEntities())
{
using (var tr = db.Database.BeginTransaction())
{
// blah, blah, a lot of entities to create, **some custom SQL, bulk inserts** etc.
db.SaveChanges();
tr.Commit();
}
}
我从表中保存时无法读取EF或原始SQL查询。但选择(NOLOCK)有效:
SELECT * FROM Table1 WITH (NOLOCK)
首先,我想知道实际发生了什么?它只是"自然"行为和表格无论锁定升级还是其他任何内容都被锁定。
第二,是否可以在插入事务级别禁用锁定?或者我是否必须添加" WITH(NOLOCK)"所有SELECT查询?
第三,是否有可能使SELECT查询在保存期间返回数据,但仅来自提交事务的记录(例如我的插入事务已添加2000条记录,3000条待处理,我进行选择查询并返回除那些以外的所有记录2000年,尚未提交)。
答案 0 :(得分:0)
db.collection.aggregate([
{$unwind : "$todo_items"},
{$group: {_id : "$_id" , completed : {{$cond :
{
if : { $and : [ {"todo_items.completed_by" : {$exists: true, $ne : null }},
{"todo_items.completed_date" : {$exists : true, $ne : null}} ] } },
then : {$push : {"old_completed" : "$todo_items"}},
else: {$push : {"old_incompleted" : "$todo_items"}}
} } } },
{$project: {_id : "$_id", completed : "$completed.old_completed" ,
incompleted : "$completed.old_incompleted"}}
]);
提示;有人称之为bad habit to kick。看看TRANSACTION ISOLATION LEVEL在以更加可控的方式处理此类问题时可能会有用。答案 1 :(得分:0)
表格未锁定。插入的特定记录已被锁定。您注意到阻塞是因为在提交之前尝试读取这些新插入的行。
在数据库中启用读提交的快照。
ALTER DATABASE <yourdb> SET READ_COMMITTED_SNAPSHOT ON;
有些人希望了解可能的lock escalation,missing indexes causing scans和cost of row level isolation。