Еще больше запутался, чем когда-либо, с единицами работы по сравнению с отсутствием и уклонением от микроуправления транзакциями в репозитории!

Я пришел к выводу, что нет причин использовать UnitOfWork поверх сеанса NHibernate, и спрашивал в этот вопрос о том, как лучше всего не создавать транзакцию явно для каждого действия сохранения базы данных.

Только для того, чтобы вернуться к идее единицы работы. Что ж, дальнейшее расследование привело меня к тому, что я изначально не собирался реализовывать отдельный шаблон Unit of Work поверх NHibernate (один пример и другие).

Моя проблема в том, как вы не используете единицу работы и не управляете транзакциями в репозитории на микроуровне и не храните их отдельно?


person pghtech    schedule 03.05.2011    source источник
comment
Я думал, что управление образом жизни nHibernate позаботится об этом за вас. В чем проблема с использованием per-request?   -  person Oded    schedule 03.05.2011
comment
У меня нет проблем с каждым запросом, это отделение моего репозитория от транзакции.   -  person pghtech    schedule 03.05.2011


Ответы (1)


Вы по-прежнему можете отделить репозиторий от транзакции. Главное, чем вам придется управлять, — это жизненный цикл вашего сеанса.

В вашем диспетчере транзакций вы можете написать что-то вроде

public class TransactionManager
{
    private ISession session;

    public TransactionManager(ISession session)
    {
        this.session = session;
    }

    public void BeginTransaction()
    {
         session.BeginTransaction();
    }

    public void CommitTransaction()
    {
        session.Transaction.Commit();
    }
}

Затем в вашем репозитории вы просто вводите сеанс

public class Repository
{
    private ISession session;

    public Repository(ISession session)
    {
        this.session = session;
    }

    public T Get<T>(int id)
    {
        return session.Get<T>(id);
    }
}

Если вы используете тот же сеанс в диспетчере транзакций, что и репозиторий. Ваш репозиторий будет работать с явной транзакцией.

person Vadim    schedule 03.05.2011
comment
Я делал то же самое с единицей работы, которая, как я думаю, более или менее соответствует тому, что вы изложили, - что я не могу понять, так это то, что если вы не передаете экземпляр TransactionManager в репозиторий, как бы вы когда-нибудь вызывали BeginTransaction() или CommitTransaction()? - person pghtech; 03.05.2011
comment
Это не единица реализации работы. Однако его можно использовать в реализации единицы работы. Если вы не хотите, чтобы репозиторий управлял транзакцией на микроуровне, код, использующий репозиторий, должен будет управлять транзакцией. - person Vadim; 03.05.2011
comment
В порядке. Но все же, как вы собираетесь вызывать любой из этих методов, если вы не передаете объект TransactionManager? - person pghtech; 03.05.2011
comment
Передать на что? Предположительно код, использующий репозиторий, будет иметь экземпляр диспетчера транзакций. Поскольку, на мой взгляд, это огромная боль и нарушение шаблонов, таких как инверсия управления, я бы просто использовал шаблон единицы работы для управления своими транзакциями. - person Vadim; 03.05.2011