Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用EF'进行交易时出现异常;s DbContext.ExecuteSqlCommand()_C#_Sql Server_Entity Framework 6 - Fatal编程技术网

C# 使用EF'进行交易时出现异常;s DbContext.ExecuteSqlCommand()

C# 使用EF'进行交易时出现异常;s DbContext.ExecuteSqlCommand(),c#,sql-server,entity-framework-6,C#,Sql Server,Entity Framework 6,使用try-catch结构,我试图找出在事务的任何一点中捕获异常时该怎么办。下面是一个代码示例: try { DbContext.ExecuteSqlCommand("BEGIN TRANSACTION"); //Line 1 DBContext.ExecuteSqlCommand("Some Insertion/Deletion Goes Here"); //Line 2 DbContext.ExecuteSqlCommand("COMMIT");

使用try-catch结构,我试图找出在事务的任何一点中捕获异常时该怎么办。下面是一个代码示例:

try
{
   DbContext.ExecuteSqlCommand("BEGIN TRANSACTION");        //Line 1
   DBContext.ExecuteSqlCommand("Some Insertion/Deletion Goes Here"); //Line 2
   DbContext.ExecuteSqlCommand("COMMIT");                   //Line 3
}
catch(Exception)
{
}   
如果在执行“第1行”时发现expection,则除了发出错误警报外,无需执行任何操作。如果它执行第二行时被捕获,我不知道是否需要尝试回滚成功打开的事务,如果第三行出现问题,也会发生同样的情况

我应该发送一个回滚吗?或者在一次方法调用中直接将所有命令发送给银行

在try-catch中,有一个循环执行许多事务,比如示例中的事务(我需要很多小事务,而不仅仅是一个大事务,这样我就可以正确地重用SQL的'_-log'文件,避免它不必要地增长)

如果任何一个事务出错,我只需要将它们全部删除,并告知发生了什么,但我不能将其转换为一个大事务,只需使用回滚,否则它将使日志文件增长到40GB

我想这会有帮助:

using (var ctx = new MyDbContext())
{
    // begin a transaction in EF – note: this returns a DbContextTransaction object
    // and will open the underlying database connection if necessary
    using (var dbCtxTxn = ctx.Database.BeginTransaction())
    {
       try
       {
            // use DbContext as normal - query, update, call SaveChanges() etc. E.g.:
           ctx.Database.ExecuteSqlCommand(
               @"UPDATE MyEntity SET Processed = ‘Done’ "
               + "WHERE LastUpdated < ‘2013-03-05T16:43:00’");

           var myNewEntity = new MyEntity() { Text = @"My New Entity" };
           ctx.MyEntities.Add(myNewEntity);
           ctx.SaveChanges();

           dbCtxTxn.Commit();
       }
       catch (Exception e)
       {
           dbCtxTxn.Rollback();
       }
    } // if DbContextTransaction opened the connection then it will close it here
}
使用(var ctx=new MyDbContext())
{
//在EF中开始事务–注意:这将返回DbContextTransaction对象
//并将在必要时打开基础数据库连接
使用(var dbCtxTxn=ctx.Database.BeginTransaction())
{
尝试
{
//使用DbContext作为常规-查询、更新、调用SaveChanges()等。例如:
ctx.Database.ExecuteSqlCommand(
@“已处理更新MyEntity集='Done'”
+“其中最新更新<'2013-03-05T16:43:00'”;
var myNewEntity=newmyentity(){Text=@“我的新实体”};
ctx.MyEntities.Add(myNewEntity);
ctx.SaveChanges();
dbCtxTxn.Commit();
}
捕获(例外e)
{
dbCtxTxn.Rollback();
}
}//如果DbContextTransaction打开了连接,那么它将在此处关闭连接
}
摘自:


基本上,它的思想是,您的事务成为using块的一部分,在其中,您可以使用实际的sql进行try/catch。如果try/catch中出现任何失败,它将从Entity Framework 6开始回滚,
ExecuteSqlCommand
将使用其自己的事务进行包装,如下所述:

除非您显式地需要将多个sql命令滚动到单个事务中,否则不需要显式地开始新的事务作用域

关于事务日志增长,假设您的目标是Sql Server,那么将事务日志操作设置为
simple
将确保在检查点之间回收日志


显然,如果在整个导入过程中没有维护事务日志历史记录,那么就没有隐式机制在失败时回滚所有数据。为了简单起见,如果我需要在出错时删除所有行,我可能只会在表中添加一个“created”datetime字段,并根据对created字段的筛选将其从表中删除。

值得注意的是,这仅适用于EF 6。对于较旧版本的EF,如果我没有弄错术语,您应该使用TransactionScope(请参阅)。这是一种事务范围,但当我根本不需要使用实体时,这有用吗?对于将整个事务编写为单个查询“begin transaction/n Insert stuff/n commit”,您的答案有什么不同?从示例中可以看出,他不是在处理实体,而是在处理内联sql。这样做的好处是它消除了您的问题-您不必担心捕获是如何/在何处发生的,它将被回滚,不管发生了什么。如果事务无法打开,会发生什么情况?使用块将被跳过?我说要“正确”使用它哈哈哈,我这么说是因为当我尝试使用单个查询来完成任务时,日志文件将增长到接近40Gb,以前它的容量大约为6gb,所以我创建了一些小批处理,当前面的操作完成时,这些批处理将重用日志文件,因此不会超出需要扩展日志文件。恢复模型已经设置为简单,但是这个巨大的查询让我发疯。无论如何,谢谢你的回答=]