У меня есть некоторая основная таблица (например, Companies) и множество зависимых таблиц (например, CompanyAddresses, CompanyPaymentInfos и т. Д.) В моей базе данных Postgres:
CREATE TABLE Companies (
Id uuid NOT NULL PRIMARY KEY,
...);
CREATE TABLE CompanyAddresses(
CompanyId uuid NOT NULL PRIMARY KEY REFERENCES Companies(Id),
...);
CREATE TABLE CompanyPaymentInfos(
CompanyId uuid NOT NULL PRIMARY KEY REFERENCES Companies(Id),
...);
Я использую транзакции из стандартной библиотеки в моем C #code:
private TransactionScope GeTransactionScope()
{
return new TransactionScope(
TransactionScopeOption.RequiresNew,
new TransactionOptions
{
IsolationLevel = IsolationLevel.ReadCommitted
},
TransactionScopeAsyncFlowOption.Enabled);
}
private async Task DoChange(...)
{
using (var scope = GeTransactionScope())
{
await Insert(Company);
await Task.WhenAll(
Insert(CompanyPaymentInfo),
Insert(CompanyAddress),
Insert(CompanyTags),
// so on
);
scope.Complete();
}
}
Каждая команда Insert
производит только выполнение кода SQL без каких-либо внутренних транзакций.
И после выполнения DoChange я получаю эту ошибку:
Npgsql.PostgresException (0x80004005): 23503: вставка или обновление таблицы "companyaddresses" нарушает ограничение внешнего ключа "companyaddresses_companyid_fkey"
И, конечно, у меня многовопросы типа:
- Почему я получаю ошибку?
- Почему я получаю ошибку во время вставки CompanyAddress, а не CompanyPaymentInfo?
Если я переключаю DoChange
на последовательное выполнение, все работает нормально:
private void DoChange()
{
using (var scope = GeTransactionScope())
{
await Insert(Company);
await Insert(CompanyPaymentInfo);
await Insert(CompanyAddress);
await Insert(CompanyTags);
// ...
scope.Complete();
}
}
Может быть, это поможет:
- Я использую Net Core 2.0
- Iиспользовать Postgres 10.4 со стандартным наборомtings (ReadCommitted в качестве уровня изоляции и т. д.).Кроме того, я добавил
enlist=true
в строку подключения, чтобы транзакции работали. - Я использую Npgsql 3.2.5 и Dapper 1.50.2 внутри моей команды
Insert