简体   繁体   English

EF 核心事务原始 SQL memory 使用

[英]EF Core Transactions raw SQL memory use

I'm trying to understand how EF Core transaction with a lot of inner commands use memory.我试图了解具有大量内部命令的 EF Core 事务如何使用 memory。

Let's say I have code like this:假设我有这样的代码:

using var reader = new MyReader(myStream);
using var context = new BloggingContext();
using var transaction = context.Database.BeginTransaction();

try
{
    while (!reader.EndOfStream()) 
    {
        var myObj = reader.ReadNextObject();
        context.Database.ExecuteSqlRaw("INSERT INTO [MyTable] ([Col1], [Col2]) VALUES ({0}, {1})", 
                                       myObj.prop1, myObj.prop2);
    }

    transaction.Commit();
}
catch (Exception)
{
    // Exception handling
}

MyReader is reading a very large (millions of rows) collection of records streamed from some source. MyReader正在读取从某个来源流式传输的非常大(数百万行)的记录集合。

My questions are:我的问题是:

  1. Can objects referenced by myObj variable be garbage collected before we commit the transaction, or are we effectively loading all of them into memory? myObj变量引用的对象是否可以在我们提交事务之前被垃圾回收,或者我们是否有效地将它们全部加载到 memory 中?

  2. Are all SQL commands we set to execute stored in memory until we commit the transaction, or are they sent to the database immediately?我们设置要执行的所有SQL命令都存储在memory中直到我们提交事务,还是立即发送到数据库?

  3. Am I understanding correctly, that this would lock [MyTable] until we commit the transaction?我是否理解正确,这会锁定[MyTable]直到我们提交事务?

Can objects references by myObj variable be garbage collected before we commit the transaction在我们提交事务之前,myObj 变量引用的对象可以被垃圾收集吗

Yes.是的。 Once ExecuteSqlRaw completes, EF will not hold any references to the object that myObj refers to, and it can be collected.一旦 ExecuteSqlRaw 完成,EF 将不会保留对 myObj 引用的 object 的任何引用,并且可以收集它。

Are all SQL commands we set to execute stored in memory until we commit the transaction, or are they sent to the database immediately?我们设置要执行的所有SQL命令都存储在memory中直到我们提交事务,还是立即发送到数据库?

They are sent to the database immediately by ExecuteSqlRaw , the row is inserted and transaction log records written to the in-memory log buffer.它们被ExecuteSqlRaw立即发送到数据库,插入行并将事务日志记录写入内存中的日志缓冲区。 The transaction just prevents the statement from waiting until the log records are hardened to disk, and allows you to roll back the whole transaction.事务只是阻止语句等到日志记录硬化到磁盘,并允许您回滚整个事务。 And even the log records are not kept in memory on the server;而且连日志记录都没有保存在服务器上的memory; they will be hardened to the log files asynchronously, and read back from there in the case of a rollback.它们将被异步地加固到日志文件中,并在回滚的情况下从那里读回。

Am I understanding correctly, that this would lock [MyTable] until we commit the transaction?我是否理解正确,这会锁定 [MyTable] 直到我们提交事务?

SQL Server will lock only the inserted rows, unless you inserted so many that it triggered lock escalation. SQL 服务器将只锁定插入的行,除非您插入的行太多以至于触发了锁升级。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM