Транзакции через несколько методов DAL из одного метода в BLL

Вместо этого я использовал словарь, но все еще не уверен, есть ли более быстрый способ извлечь значение из коллекции:

var Lookup = Lines.Entities.Where(e => e.GetAttributeValue<OptionSetValue>("new_time").Value == 100000001).Select(r => new
                    {
                        group = r.GetAttributeValue<OptionSetValue>("new_group").Value,
                        desc = r.GetAttributeValue<string>("new_desc"),
                        numbers = new Dictionary<string, int>()
                        {
                            {"monday", r.GetAttributeValue<int>("new_mondayunits") },
                            {"tuesday", r.GetAttributeValue<int>("new_tuesdayunits") },
                            {"wednesday", r.GetAttributeValue<int>("new_wednesdayunits") },
                            {"thursday", r.GetAttributeValue<int>("new_thursdayunits") },
                            {"friday", r.GetAttributeValue<int>("new_fridayunits") }
                        }
                    }).ToDictionary(t => t.group.ToString() + t.desc, t => t.numbers);
var quan = Lookup.ContainsKey(key) ? amLookup[key][currentday] : 0;
6
задан Mike 29 January 2009 в 22:01
поделиться

4 ответа

хорошо, во-первых, необходимо будет придерживаться атомарной Единицы работы, которую Вы указываете как отдельный метод в Вашем BLL. Это (например), создало бы клиента, порядок и объекты порядка. Вы затем перенесли бы это все аккуратно в операторе использования TransactionScope. 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 мс). компромисс между простой транзакцией точки контакта по сравнению с (громоздкими) альтернативами смягчает (для меня и моих клиентов) ту начальную задержку 'загрузки'.

просто требуемый, чтобы продемонстрировать, что простота не прибывает без компромисса (хотя в начальных этапах)

8
ответ дан 8 December 2019 в 16:10
поделиться

То, что Вы описываете, является самым 'определением' долгой транзакции.

Каждый метод DAL мог просто обеспечить операции (без любых определенных фиксаций). Ваш BLL (который является в действительности, где Вы координируете любые вызовы к DAL так или иначе) - то, где можно принять решение или фиксировать, или выполнить 'точку сохранения'. Точка сохранения является дополнительным объектом, который можно использовать для разрешения 'откатов' в рамках длительной транзакции.

Так, например, если бы мой DAL имеет методы DAL1, DAL2, DAL3 все изменчивы, они просто 'выполнили' бы операции изменения данных (т.е. некоторый тип Создают, Обновление, Удаляют). От моего BLL, позволяет, предполагают, что у меня есть BL1, и методы BL2 (BL1 длителен). BL1 вызывает все вышеупомянутые методы DAL (т.е. DAL1... DAL3), в то время как BL2, только вызывает DAL3.

Поэтому на осуществлении каждого метода бизнес-логики у Вас могло бы быть следующее:

BL1 (длинная транзакция)-> {точка сохранения} DAL1-> {точка сохранения} DAL2-> DAL3 {фиксация/конец}

BL2-> DAL3 {фиксация/конец}

Идея позади 'точки сохранения' - это, может позволить BL1 откатывать в любой точке, если существуют проблемы в операциях данных. Долгая транзакция ТОЛЬКО фиксируется, если все три операции успешно завершаются. BL2 может все еще назвать любой метод в DAL, и это ответственно за управление фиксациями.Примечание: Вы могли использовать 'точки сохранения' в коротких/регулярных транзакциях также.

4
ответ дан 8 December 2019 в 16:10
поделиться

Хороший вопрос. Это добирается до сути несоответствия импеданса.

Это - один из самых сильных аргументов в пользу использования хранимых процедур. Причина: они разработаны для инкапсуляции нескольких SQL-операторов в транзакции.

То же может быть сделано процедурно в DAL, но это приводит к коду с меньшей ясностью, в то время как обычное приведение к перемещению связи/сцепления балансируется в неправильном направлении.

Поэтому я реализую DAL в более высоком уровне абстракции, чем простая инкапсуляция таблиц.

2
ответ дан 8 December 2019 в 16:10
поделиться

на всякий случай мой комментарий в исходной статье не 'придерживался', вот то, что я добавил как дополнительная информация:

<-----одновременно, просто заметил, что другая подобная ссылка на это отправила спустя несколько часов после Вашего запроса. использует подобную стратегию и мог бы стоить Вас смотрящий на также: http://stackoverflow.com/questions/494550/how-does-transactionscope-roll-back-transactions----->

1
ответ дан 8 December 2019 в 16:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: