AAV*_*AAV 2 c# entity-framework transactions
我正在使用实体框架,我有几种方法,我正在使用事务.我收到此错误:连接已在事务中,无法参与另一个事务.EntityClient不支持并行事务. 我有多种方法,取决于'MethodB',如下面的代码示例:
public void MethodA(){
using (var tran = Db.Database.BeginTransaction()){
MethodB();
var tableARecord = new TableARecord();
try
{
_context.TableAs.Add(tableARecord)
Db.SaveChanges();
}
catch (Exception excp)
{
tran.Rollback();
throw;
}
}
}
public void MethodC(){
using (var tran = Db.Database.BeginTransaction()){
MethodB();
//do something else
}
}
public int MethodB(){
int ret = 0
//exception happens when starting the transaction below
using (var tran = Db.Database.BeginTransaction()){
//do something else
}
return ret;
}
Run Code Online (Sandbox Code Playgroud)
在打开新事务之前,您需要提交前一个事务,因此您不应该在上一个事务中打开新事务.
public void MethodA(){
using (var tran = Db.Database.BeginTransaction()){
try
{
MethodB();
var tableARecord = new TableARecord();
_context.TableAs.Add(tableARecord)
Db.SaveChanges();
}
catch (Exception excp)
{
tran.Rollback();
throw;
}
}
}
public int MethodB(){
int ret = 0
//exception happens when starting the transaction below
// The transaction is already open, you should not open a new one.
//do something else
return ret;
}
Run Code Online (Sandbox Code Playgroud)
但是,你这样做是一种反模式.打开事务时未进行的每次"保存更改"都是单个事务.
您应该做的是在您的业务逻辑中开始您的事务,并在同一级别提交它.
// Business Logic :
var transaction = Db.Database.BeginTransaction())
try {
_Repository.MethodA();
_Repository.MethodB();
transaction.Commit();
}
catch(){
transaction.Rollback();
}
//Repository :
public void MethodA(){
var tableARecord = new TableARecord();
_context.TableAs.Add(tableARecord)
Db.SaveChanges();
}
public void MethodA(){
// Just do some other stuff
Db.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
小智 5
让我为您提供已回答问题的替代方案。
您可以检查交易是否已创建并使用它。
public async Task MethodA()
{
using(var transaction = await context.BeginTransaction() )
{
await MethodB(transaction);
//...
transaction.Commit();
}
}
public async Task MethodB(IDbContextTransaction transaction)
{
var isOpen = transaction != null;
try
{
if (!isOpen)
{
transaction = await context.BeginTransaction();
}
//...
if (!isOpen)
{
transaction.Commit();
}
}
finally
{
if (!isOpen)
{
transaction.Dispose();
}
}
}
Run Code Online (Sandbox Code Playgroud)
通过调用MethodA();随后调用MethodB(transaction);,它将使用当前事务
通过调用MethodB(null);,它将创建一个新事务并使用它