当前位置:  开发笔记 > 编程语言 > 正文

从BLL中的一个方法跨多个DAL方法进行的事务

如何解决《从BLL中的一个方法跨多个DAL方法进行的事务》经验,为你挑选了1个好方法。

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

可以从BLL中的其他位置单独调用每个DAL方法,因此无法保证数据层方法始终是事务的一部分.我们需要这个功能,所以如果数据库在长时间运行的过程中脱机,就没有提交.业务层基于每个先前调用的结果来编排不同的数据层方法调用.我们只想在整个过程的最后提交(从业务层).



1> 小智..:

首先,您必须遵守您在BLL中指定为单个方法的原子工作单元.这将(例如)创建客户,订单和订单商品.然后,您可以将所有内容整齐地包装在TransactionScope using语句中.TransactionScope是这里的秘密武器.下面是一些代码,幸运的是我现在正在努力:):

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;
}

希望你能得到主旨.基本上,它是一个成功或失败的工作,无论任何不同的数据库(即在上面的例子中,艺术家和artistartistgenre可以托管在两个单独的数据库存储,但TransactionScope不关心它,它在COM +级别工作并管理原子性它可以"看到"的范围

希望这可以帮助

编辑:您可能会发现TransactionScope的初始调用(在应用启动时)可能会略微明显(例如,在上面的示例中,如果是第一次调用,可能需要2-3秒才能完成),但是,后续呼叫几乎是瞬时的(即通常为250-750毫秒).简单的联系交易与(笨重的)替代方案之间的权衡减轻了(对我和我的客户而言)最初的"加载"延迟.

只是想证明轻松不会妥协(尽管在初始阶段)

推荐阅读
mobiledu2402851203
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有