在几个DAL方法交易从BLL的一种方法 [英] Transactions across several DAL methods from the one method in the BLL

查看:126
本文介绍了在几个DAL方法交易从BLL的一种方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你会如何去调用多种方法中的数据访问层从一个方法,业务逻辑层,使所有的SQL命令居住在一个SQL事务?

How would you go about calling several methods in the data access layer from one method in the business logic layer so that all of the SQL commands lived in one SQL transaction?

的DAL方法,每个人可以单独从其他地方BLL调用,所以不能保证该数据层的方法,始终是交易的一部分。我们需要这种功能,因此,如果数据库脱机,在一个长期运行的过程当中,有没有犯。业务层是策划基于每个的previous调用的结果不同数据层的方法调用。我们只希望提交(从业务层),在整个过程的最后。

Each one of the DAL methods may be called individually from other places in the BLL, so there is no guarantee that the data layer methods are always part of a transaction. We need this functionality so if the database goes offline in the middle of a long running process, there's no commit. The business layer is orchestrating different data layer method calls based on the results of each of the previous calls. We only want to commit (from the business layer) at the very end of the entire process.

推荐答案

嗯,首先,你必须坚持工作指定为您的BLL了一个方法,一个原子单元。这(例如)创建客户,订单和订单项目。你那么一个TransactionScope内using语句包装这一切都整齐了。的TransactionScope是秘密武器在这里。下面是一些code表示幸运的是我的工作现在:):

well, firstly, you'll have to adhere to an atomic Unit of Work that you specify as a single method in your BLL. This would (for example) create the customer, the order and the order items. you'd then wrap this all neatly up inside a TransactionScope using statement. TransactionScope is the secret weapon here. below is some code that luckily enough I'm working on right now :):

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 +水平和管理的原子适用范围,它可以看到)的

hopefully, you'll get the gist. basically, it's an all succeed or fail job, irrespective of any disparate databases (i.e. in the above example, artist and artistartistgenre could be hosted in two separate db stores but TransactionScope would care less about that, it works at COM+ level and manages the atomicity of the scope that it can 'see')

希望这有助于

编辑:您可能会发现的TransactionScope的初始调用(在应用程序启动时)可能会稍微明显的(即在上面的例子中,如果要求在第一时间,可以采取2-3秒即可完成),不过,随后的调用是的几乎的瞬间(即通常为250-750毫秒)。权衡一个简单的点接触式交易的VS(笨重的)替代减轻之间(对我和我的客户),最初的'负荷'延迟。

you'll possibly find that the initial invocation of TransactionScope (on app start-up) may be slightly noticeable (i.e. in the example above, if called for the first time, can take 2-3 seconds to complete), however, subsequent calls are almost instantaneous (i.e. typically 250-750 ms). the trade off between a simple point of contact transaction vs the (unwieldy) alternatives mitigates (for me and my clients) that initial 'loading' latency.

只是想证明,便于并不是没有妥协的(尽管在初始阶段)

just wanted to demonstrate that ease doesn't come without compromise (albeit in the initial stages)

这篇关于在几个DAL方法交易从BLL的一种方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆