在使用ef 39;s DbContext.ExecuteSqlCommand()的事务期间出现异常
本文关键字:事务 异常 ExecuteSqlCommand DbContext ef | 更新日期: 2023-09-27 18:12:28
使用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)
{
}
如果期望在执行'Line 1'时被捕获,除了警告错误之外,什么都不能做。如果它被捕获执行第二行,我不知道我是否需要尝试回滚成功打开的事务,如果第三行出现问题,也会发生同样的情况。
我应该发送回滚吗?或者在一个方法调用中将所有命令直接发送到银行?
在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
}
取自:https://entityframework.codeplex.com/wikipage?title=Improved%20Transaction%20Support
基本上,它的想法是你的事务成为using块的一部分,在其中你有一个实际的sql的try/catch。如果在try/catch中有任何失败,它将被回滚
从实体框架6开始,ExecuteSqlCommand
被自己的事务包裹,如下所示:http://msdn.microsoft.com/en-gb/data/dn456843.aspx
除非您显式地需要将多个sql命令滚动到单个事务中,否则没有必要显式地开始一个新的事务范围。
关于事务日志的增长,假设您的目标是Sql Server,那么将事务日志操作设置为simple
将确保日志在检查点之间被回收。
显然,如果没有在整个导入过程中维护事务日志历史记录,则没有在发生故障时回滚所有数据的隐式机制。为了保持简单,我可能只会添加一个'created' datetime字段到表中,如果我需要在发生错误的情况下删除所有行,则基于对已创建字段的过滤器从表中删除。