【发布时间】:2019-10-16 15:12:25
【问题描述】:
我无法弄清楚为什么 TransactionScope 正在启动分布式事务(未在 SQL Server 上配置)。我想改用本地事务,当两个数据库位于同一个 SQL Server 实例中时可以使用它。我的代码有什么问题,我该如何解决?我可以强制 Transaction Scope 先尝试本地事务吗?
数据库
appsettings.json
{
"ConnectionStrings": {
"DefaultConnection": "Data Source=DESKTOP;Initial Catalog=test;Integrated Security=True",
"Test2Connection": "Data Source=DESKTOP;Initial Catalog=test2;Integrated Security=True"
}
}
startup.cs注册TestContext和Test2Context
services.AddDbContext<TestContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddDbContext<Test2Context>(options =>
options.UseSqlServer(Configuration.GetConnectionString("Test2Connection")));
services.AddTransient<ICustomerRepository, CustomerRepository>();
services.AddTransient<IMaterialRepository, MaterialRepository>();
// This service inject TestContext and Test2Context
services.AddTransient<ICustomerService, CustomerService>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
CustomerRepository 使用 TestContext
public class CustomerRepository : ICustomerRepository
{
private readonly TestContext _context;
public CustomerRepository(TestContext context)
{
_context = context;
}
public Customer Retrieve(int id)
{
return _context.Customers.Where(x => x.Id == id).FirstOrDefault();
}
}
MaterialRepository 使用 Test2Context
public class MaterialRepository : IMaterialRepository
{
private readonly Test2Context _context;
public MaterialRepository(Test2Context context)
{
_context = context;
}
public Material Retrieve(int id)
{
return _context.Materials.Where(x => x.Id == id).FirstOrDefault();
}
}
客户服务
public class CustomerService : ICustomerService
{
private readonly ICustomerRepository _customerRepository;
private readonly IMaterialRepository _materialRepository;
public CustomerService(
ICustomerRepository customerRepository,
IMaterialRepository materialRepository)
{
_customerRepository = customerRepository;
_materialRepository = materialRepository;
}
public void DoSomething()
{
using (var transaction = new TransactionScope(TransactionScopeOption.Required
//,new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead }
))
{
var customer = _customerRepository.Retrieve(1);
var material = _materialRepository.Retrieve(1); // The exception is thrown here !
// _customerRepository.Save(customer);
transaction.Complete();
}
}
}
读取第二个上下文 throw 的 This platform does not support distributed transactions 异常。
当对两个数据库上下文使用相同的连接字符串时,分布式事务也会触发
startup.cs
services.AddDbContext<TestContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddDbContext<TestReadOnlyContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
CustomerReadOnlyRepository
public class CustomerReadOnlyRepository : ICustomerReadOnlyRepository
{
private readonly TestReadOnlyContext _context;
public CustomerReadOnlyRepository(TestReadOnlyContext context)
{
_context = context;
}
public Customer Retrieve(int customerId)
{
Customer customer = _context.Customers.Where(x => x.Id == customerId).Include("Offices").FirstOrDefault();
return customer;
}
}
客户服务
var customer = _customerRepository.Retrieve(1);
var customerReadOnly = _customerReadOnlyRepository.Retrieve(1); // Throw's the same error.
【问题讨论】:
标签: sql-server entity-framework-core dbcontext transactionscope distributed-transactions