[英]How to retrieve the value of an ID column inside a transaction that is never committed?
[英]How to return if a transaction is committed or not?
我想检查事务是否已提交并返回值。
我写了下面的代码,但我不确定如何返回它是否成功。
public Task Insert(List<PortfolioCompanyLinkModel> record, CancellationToken cancellationToken = default(CancellationToken))
{
using (var transaction = _context.Database.BeginTransaction())
{
try
{
foreach (var item in record)
{
PortfolioCompanyLink portfolioCompanyLink = new PortfolioCompanyLink();
portfolioCompanyLink.PortfolioCompanyId = item.PortfolioCompanyId;
portfolioCompanyLink.URL = item.URL;
portfolioCompanyLink.LinkId = item.LinkId;
portfolioCompanyLink.CreatedBy = portfolioCompanyLink.ModifiedBy = _loggedInUser;
portfolioCompanyLink.CreatedOn = portfolioCompanyLink.ModifiedOn = DateTime.UtcNow;
_context.PortfolioCompanyLink.AddAsync(portfolioCompanyLink, cancellationToken);
}
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
}
}
//return _context.PortfolioCompanyLink.AddAsync(record, cancellationToken);
}
请帮我在这里写退货声明
如果您想返回一个指示“成功与否”的值,您应该将方法的返回类型更改为Task<bool>
并返回一个bool
:
public async Task<bool> Insert(List<PortfolioCompanyLinkModel> record, CancellationToken cancellationToken = default(CancellationToken))
{
using (var transaction = _context.Database.BeginTransaction())
{
try
{
foreach (var item in record)
{
PortfolioCompanyLink portfolioCompanyLink = new PortfolioCompanyLink();
portfolioCompanyLink.PortfolioCompanyId = item.PortfolioCompanyId;
portfolioCompanyLink.URL = item.URL;
portfolioCompanyLink.LinkId = item.LinkId;
portfolioCompanyLink.CreatedBy = portfolioCompanyLink.ModifiedBy = _loggedInUser;
portfolioCompanyLink.CreatedOn = portfolioCompanyLink.ModifiedOn = DateTime.UtcNow;
await _context.PortfolioCompanyLink.AddAsync(portfolioCompanyLink, cancellationToken);
}
transaction.Commit();
return true;
}
catch (Exception ex)
{
transaction.Rollback();
return false;
}
}
}
在上面的示例代码中,我还将该方法标记为async
并等待AddAsync
方法。
您可以使用以下内容:
Transaction.Current.TransactionInformation.Status
获取状态:
它是一个枚举。 根据 MSDN:
中止 2
事务已回滚。
活动 0
交易的状态是未知的,因为某些参与者仍然必须被轮询。
承诺 1
事务已提交。
疑点3
您的代码可能如下所示:
public Task Insert(List<PortfolioCompanyLinkModel> record, CancellationToken cancellationToken = default(CancellationToken))
{
using (var transaction = _context.Database.BeginTransaction())
{
try
{
foreach (var item in record)
{
PortfolioCompanyLink portfolioCompanyLink = new PortfolioCompanyLink();
portfolioCompanyLink.PortfolioCompanyId = item.PortfolioCompanyId;
portfolioCompanyLink.URL = item.URL;
portfolioCompanyLink.LinkId = item.LinkId;
portfolioCompanyLink.CreatedBy = portfolioCompanyLink.ModifiedBy = _loggedInUser;
portfolioCompanyLink.CreatedOn = portfolioCompanyLink.ModifiedOn = DateTime.UtcNow;
_context.PortfolioCompanyLink.AddAsync(portfolioCompanyLink, cancellationToken);
}
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
}
finally
{
var status = transaction.TransactionInformation.Status;
if (status.Committed)
return true;
return false;
}
}
//return _context.PortfolioCompanyLink.AddAsync(record, cancellationToken);
}
mm8 的回答解释了如果代码成功与否,如何返回真/假。 没有理由检查事务的状态,因为调用 Commit 或 Rollback 的是代码本身。 即使Commit
抛出, catch
块也会执行 - 并再次抛出,因为事务已经回滚。
不过,EF/EF Core 中不需要此类代码。 DbContext 缓存所有更改,并且仅在调用SaveChanges
时将它们保存到数据库中。 基本保存教程中的单个 SaveChanges中的多个操作部分解释了:
对于大多数数据库提供程序,SaveChanges 是事务性的。 这意味着所有操作要么成功要么失败,并且这些操作永远不会被部分应用。
将多个对象保存到数据库所需的一切是:
foreach (var item in record)
{
PortfolioCompanyLink portfolioCompanyLink = new PortfolioCompanyLink();
.....
//In-memory operation only. Doesn't need awaiting. Doesn't change the database
//This only modifies the in-memory entities tracked by the context
_context.PortfolioCompanyLink.Add(portfolioCompanyLink);
}
//Writes *all* changes to the database in a single transaction
await _context.SaveChangesAsync(cancellationToken);
不需要显式事务。 SaveChangesAsync
将回滚任何更改并在出现任何问题时抛出。
事实上,尝试在每一步都按照自定义AddAsync
方法的方式调用SaveChangesAsync
会产生意想不到的后果。 SaveChangesAsync
保存所有更改,而不仅仅是最后一个。 如果该上下文有待删除的更新,则对AddAsync
的第一次调用可能最终会删除或更新记录。
显式长时间运行的事务的另一个问题是它们严重损害了可扩展性,即使对于小型应用程序也是如此。 一个事务不断更新它所接触的行和表,阻止其他事务。 无缘无故地保持事务活动会导致阻塞甚至死锁。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.