我正在尝试创建一个封装 4 个数据库表插入和 2 个更新的事务。
我“主要”在工作。我的意思是,如果我在这 6 个 db 交互中的任何一个中遇到错误,则会发生先前的回滚......除了第一个。第一个是对表头表的插入...随后对明细表甚至另一个表头表的插入等...所有回滚...但是如果在回滚后您检查表,它们都将没有记录,除了第一个。
//Create receipt, ic, printq; update pod, poh
public List<ActionConfirmation<int>> CreateReceipt(
IEnumerable<ReceiptDetailPalletListViewModel> viewModelList,
int intUserId,
int intFacilityId,
int intLocationId
)
{
var dbContext = new InventoryMgmtContext();
//Opening connection
dbContext.Database.Connection.Open();
int intReceiptHdrId = 0;
int intICHdrId = 0;
var results = new List<ActionConfirmation<int>>();
foreach (ReceiptDetailPalletListViewModel viewModel in viewModelList)
{
if (viewModel.ReceivedQty > 0)
{
using (TransactionScope transaction = new TransactionScope())
{
//Create Receipt Header
ActionConfirmation<int> rcptHdrResult = CreateReceiptHeader(
dbContext,
intUserId,
intFacilityId); <===== This Tran never rolls back. Insert occured.
results.Add(rcptHdrResult);
if (!rcptHdrResult.WasSuccessful) //Recp Hdr create failed.
{
CloseFailedTrans(dbContext, transaction);
return results;
}
intReceiptHdrId = rcptHdrResult.Value;
//Create new ICHeader
ActionConfirmation<int> icHdrResult = CreateICHeader(
dbContext,
intUserId,
intFacilityId,
intLocationId,
intReceiptHdrId
);
results.Add(icHdrResult);
if (!icHdrResult.WasSuccessful)
{
CloseFailedTrans(dbContext, transaction);
return results;
}
intICHdrId = icHdrResult.Value;
//Create new ICDetail
ActionConfirmation<int> icDtlResult = CreateICDetail(
dbContext,
intICHdrId,
viewModel.ItemId,
viewModel.PODetailId,
viewModel.ReceivedQty,
intUserId
);
results.Add(icDtlResult);
if (!icDtlResult.WasSuccessful)
{
CloseFailedTrans(dbContext, transaction);
return results;
}
//Create new Recpt Detail
ActionConfirmation<int> rcptDtlResult = CreateReceiptDetail(
dbContext,
intReceiptHdrId,
viewModel.PODetailId,
viewModel.ReceivedQty,
intUserId
);
results.Add(rcptDtlResult);
if (!rcptDtlResult.WasSuccessful)
{
CloseFailedTrans(dbContext, transaction);
return results;
}
//Update PO Detail qty and Header status
List<ActionConfirmation<int>> poResults = UpdatePODetail(
dbContext,
viewModel.PODetailId,
viewModel.ReceivedQty,
intUserId
);
foreach (ActionConfirmation<int> poResult in poResults)
{
results.Add(poResult);
if (!poResult.WasSuccessful)
{
CloseFailedTrans(dbContext, transaction);
return results;
}
}
//Create new Print Q
ActionConfirmation<int> printqResult = CreatePrintQRecords(
dbContext,
intICHdrId,
intFacilityId,
intUserId
);
results.Add(printqResult);
if (!printqResult.WasSuccessful)
{
CloseFailedTrans(dbContext, transaction);
return results;
}
//Everything inserted correctly
CloseSuccessTrans(dbContext, transaction);
} //using statement
} //if rcv qty > 0
} // for each loop
dbContext.Database.Connection.Dispose();
return results;
}
以下是交易相关的方法:
// Close DB Connections and transaction
private void CloseFailedTrans(InventoryMgmtContext dbContext, TransactionScope transaction)
{
//TODO: logging
CloseTrans(dbContext, transaction);
}
// Close DB Connections and transaction
private void CloseSuccessTrans(InventoryMgmtContext dbContext, TransactionScope transaction)
{
transaction.Complete();
CloseTrans(dbContext, transaction);
}
// Close DB Connections and transaction
private void CloseTrans(InventoryMgmtContext dbContext, TransactionScope transaction)
{
transaction.Dispose();
}
这是执行插入的方法之一的示例。它们都遵循相同的模式:
//Create Receipt Header
private ActionConfirmation<int> CreateReceiptHeader(
InventoryMgmtContext dbContext,
int intUserId,
int intFacilityId
)
{
//var repository = new Repository<ReceiptHeader>(dbContext);
var repository = new ReceiptHeaderRepository(dbContext);
//Create new Receipt Header
ReceiptHeader rcptHdr = new ReceiptHeader()
{
FacilityId = intFacilityId,
StatusId = 1,
CreatedById = intUserId,
CreatedOn = DateTime.Now,
ModifiedById = intUserId,
ModifiedOn = DateTime.Now
};
return repository.Insert(rcptHdr);
}
这是存储库插入方法:
public virtual ActionConfirmation<int> Insert(TRepository entity)
{
try
{
_dataContext.Entry(entity).State = System.Data.EntityState.Added;
_dataContext.SaveChanges();
return CRUDMessage(true, "saved", entity);
}
catch (Exception ex)
{
return CRUDMessage(false, "save", entity, ex);
}
}