Я не могу понять, почему TransactionScope запускает распределенную транзакцию (которая не настроена на SQL Server). Вместо этого я хотел бы использовать локальную транзакцию, которую можно использовать, когда две базы данных расположены в одном экземпляре SQL Server. Что не так с моим кодом, как я могу это исправить? Могу ли я заставить область транзакций сначала попробовать локальную транзакцию?
Базы данных
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();
}
}
CustomerService
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();
}
}
}
чтение из второго исключения контекста 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;
}
}
CustomerService
var customer = _customerRepository.Retrieve(1);
var customerReadOnly = _customerReadOnlyRepository.Retrieve(1); // Throw's the same error.