有问题的应用程序是一个 ASP.NET Core 6 Web API。它使用 SQLite 作为数据库。目标是有朝一日将其移至 SQL Server,因此我试图严格控制数据库层。
它的独特之处在于它需要多个 SQLite 数据库,一个用于系统,一个用于当前“事件”。系统永远不会改变,但基于事物的配置方式(这可能会在调用 Web API 之间发生变化)事件数据库可以改变。
DB 层有一个
_databaseService
将创建连接:
public DbConnection CreateConnection()
{
var connection = DbFactory.CreateConnection();
if (connection != null)
{
connection.ConnectionString = ConnectionString;
connection.Open();
return connection;
}
return null;
}
DB层这样使用:
public int UpdateInvoiceItem(int priceListItemId, int qty, int invoiceItemId)
{
const string sql = "update INVOICE_ITEM set PRICE_LIST_ITEM_ID = @priceListItemId, QTY = @qty where INVOICE_ITEM_ID = @invoiceItemId";
using var conn = _databaseService.GetEventDbHelper().CreateConnection();
return conn.Execute(sql, new { priceListItemId, qty, invoiceItemId });
}
一切都很好,直到我尝试将其包装到业务层上方的
TransactionScope
一层中:
public void UpdateInvoice(Invoice invoice)
{
using var transactionScope = new TransactionScope();
foreach (var invoiceItem in invoice.InvoiceItems)
{
if (invoiceItem.Qty == 0)
{
_invoiceDs.RemoveInvoiceItem(invoiceItem.InvoiceItemId);
}
else if (invoiceItem.OrgQty != invoiceItem.Qty ||
invoiceItem.OrgPriceListItemId != invoiceItem.PriceListItemId)
{
_invoiceDs.UpdateInvoiceItem(invoiceItem.PriceListItemId, invoiceItem.Qty,
invoiceItem.PriceListItemId);
}
}
transactionScope.Complete();
}
第一次调用一切正常
_invoiceDs.UpdateInvoiceItem
,但第二次它永远不会返回,我认为这是因为事务。
我应该怎么做才能使每次获得连接时它都是
TransactionScope
的一部分? DB 层 (UpdateInvoiceItem
) 是否应该获得连接并在类的生命周期内保持连接(设置为作用域)?我应该采取完全不同的方法吗?
假设在UpdateInvoice中会多次调用UpdateInvoiceItem,在UpdateInvoiceItem方法中着实让我吃惊
using var conn = _databaseService.GetEventDbHelper().CreateConnection();
你应该首先了解TransactionScope的概念,如果你能使用
_context
,你的代码会更干净。你可以参考repo.