我使用。net 5与EF Core 5.0.5和Pomelo Mysql 5.00。
我用下面的代码测试一个事务:public async Task<IActionResult> TestTransaction()
{
var listTester = await _context.Tester.ToListAsync();
using var transaction = _context.Database.BeginTransaction();
try
{
for (int i = 0; i <= 5; i++)
{
listTester.ForEach(x =>
{
x.Value += i;
});
_context.SaveChanges();
}
transaction.Rollback();
var newLister = await _context.Tester.ToListAsync();
return Ok(newLister);
}
catch (Exception)
{
// TODO: Handle
return BadRequest("Data failed");
}
}
I have data
new Tester(){ Name = "test", Value = 0 }
当代码完成时,我收到List
new Tester(){ Name = "test", Value = 15 }
mysql数据库中的数据仍然是0,因为数据回滚,但在
var newLister = await _context.Tester.ToListAsync();
它仍然得到了Value = 15
。
为什么rollBack()
不影响当前数据?
注意:我想在每个循环上测试SaveChanges()
,我知道我可以在循环完成后放置SaveChanges
。但我只是想测试一下;)
必须清除缓存的实体。EF将不会重新加载已经修改过的实体。EF Core 5有这种可能性:
...
transaction.Rollback();
_context.ChangeTracker.Clear();
试试_context.Database.UseTransaction(transaction)
这将强制EF使用声明的事务,而不是每次调用_context.SaveChanges()
时隐式地创建一个内部事务。
文档:实体框架事务
注意:内部创建的每个事务一旦保存就会提交更改,因此需要使用您的事务。