gpt4 book ai didi

c# - 从 BLL 中的一个方法跨越多个 DAL 方法的事务

转载 作者:太空狗 更新时间:2023-10-29 20:58:02 24 4
gpt4 key购买 nike

您将如何从业务逻辑层中的一个方法调用数据访问层中的多个方法,以便所有 SQL 命令都存在于一个 SQL 事务中?

每个 DAL 方法都可以从 BLL 中的其他地方单独调用,因此不能保证数据层方法始终是事务的一部分。我们需要此功能,因此如果数据库在长时间运行的过程中脱机,则不会提交。业务层根据之前每个调用的结果编排不同的数据层方法调用。我们只想在整个过程的最后提交(从业务层)。

最佳答案

好吧,首先,您必须遵守您在 BLL 中指定为单个方法的原子工作单元。这将(例如)创建客户、订单和订单项目。然后,您可以将所有这些整齐地包装在 TransactionScope using 语句中。 TransactionScope 是这里的 secret 武器。下面是一些代码,幸运的是我现在正在处理 :):

public static int InsertArtist(Artist artist)
{
if (artist == null)
throw new ArgumentNullException("artist");

int artistid = 0;
using (TransactionScope scope = new TransactionScope())
{
// insert the master Artist
/*
we plug the artistid variable into
any child instance where ArtistID is required
*/
artistid = SiteProvider.Artist.InsertArtist(new ArtistDetails(
0,
artist.BandName,
artist.DateAdded));

// insert the child ArtistArtistGenre
artist.ArtistArtistGenres.ForEach(item =>
{
var artistartistgenre = new ArtistArtistGenreDetails(
0,
artistid,
item.ArtistGenreID);
SiteProvider.Artist.InsertArtistArtistGenre(artistartistgenre);
});

// insert the child ArtistLink
artist.ArtistLinks.ForEach(item =>
{
var artistlink = new ArtistLinkDetails(
0,
artistid,
item.LinkURL);
SiteProvider.Artist.InsertArtistLink(artistlink);
});

// insert the child ArtistProfile
artist.ArtistProfiles.ForEach(item =>
{
var artistprofile = new ArtistProfileDetails(
0,
artistid,
item.Profile);
SiteProvider.Artist.InsertArtistProfile(artistprofile);
});

// insert the child FestivalArtist
artist.FestivalArtists.ForEach(item =>
{
var festivalartist = new FestivalArtistDetails(
0,
item.FestivalID,
artistid,
item.AvailableFromDate,
item.AvailableToDate,
item.DateAdded);
SiteProvider.Festival.InsertFestivalArtist(festivalartist);
});
BizObject.PurgeCacheItems(String.Format(ARTISTARTISTGENRE_ALL_KEY, String.Empty, String.Empty));
BizObject.PurgeCacheItems(String.Format(ARTISTLINK_ALL_KEY, String.Empty, String.Empty));
BizObject.PurgeCacheItems(String.Format(ARTISTPROFILE_ALL_KEY, String.Empty, String.Empty));
BizObject.PurgeCacheItems(String.Format(FESTIVALARTIST_ALL_KEY, String.Empty, String.Empty));
BizObject.PurgeCacheItems(String.Format(ARTIST_ALL_KEY, String.Empty, String.Empty));

// commit the entire transaction - all or nothing
scope.Complete();
}
return artistid;
}

希望您能理解要点。基本上,这是一个要么成功要么失败的工作,不管任何不同的数据库(即在上面的例子中,艺术家和艺术家艺术家类型可以托管在两个单独的数据库存储中,但 TransactionScope 不太关心这一点,它在 COM+ 级别工作并管理原子性它可以“看到”的范围)

希望对你有帮助

编辑:您可能会发现 TransactionScope 的初始调用(在应用程序启动时)可能会稍微引人注意(即在上面的示例中,如果是第一次调用,可能需要2-3 秒完成),但是,后续调用几乎是瞬时的(即通常为 250-750 毫秒)。简单的联系点交易与(笨拙的)替代方案之间的权衡减轻了(对我和我的客户而言)初始“加载”延迟。

只是想证明没有妥协就没有轻松(尽管在初始阶段)

关于c# - 从 BLL 中的一个方法跨越多个 DAL 方法的事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/493649/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com