Спящий шаблон с транзакциями - PullRequest
0 голосов
/ 12 октября 2011

У меня есть веб-приложение java / spring, которое использует HibernateTemplate, и мне было интересно, можно ли использовать транзакции SQL с шаблоном hibernate.

Например, предположим, что у меня есть следующий код дао:

getHibernateTemplate().save(newObject);
getHibernateTemplate().saveOrUpdate(someObject);
getHibernateTemplate().delete(oldObject);

Предположим, что я хочу, чтобы либо все три утверждения завершились успешно, либо все три не дали результатов. Есть ли способ сделать это с помощью спящего шаблона? Могу ли я использовать блок try / catch? Если так, что бы я поместил в блок catch для отката операторов шаблона гибернации?

Ответы [ 2 ]

2 голосов
/ 12 октября 2011

Как указывало @hvgotcodes, транзакции управляются на уровне службы, а не на уровне постоянства. Это происходит из-за значения вещей, которые должны быть транзакционными =>, которые в большинстве случаев определяются бизнесом, следовательно, уровень обслуживания / домена.

Вот пример того, как выполнить ваш сервис через XML-конфигурацию Spring AOP:

<aop:config>
    <aop:pointcut id="moneyMakingBusinessServiceMethods"
                  expression="execution(* org.gitpod.startup.service.MoneyMakingBusinessService.*(..))"/>

    <aop:advisor advice-ref="moneyMakingAdvice"
                 pointcut-ref="moneyMakingBusinessServiceMethods"/>
</aop:config>

<tx:advice id="moneyMakingAdvice" transaction-manager="txManager">
    <tx:attributes>
        <tx:method name="makeMoney" propagation="REQUIRED"/>
        <tx:method name="withdrawMoney" propagation="REQUIRED" read-only="true"/>            
        <tx:method name="*" propagation="SUPPORTS" read-only="true"/>
    </tx:attributes>
</tx:advice>

Этот подход хорош, потому что вам не нужно загрязнять свои услуги аннотациями @Transactional, @SomethingElse, а все управление / конфигурация вашего TX определяется в одном месте [это мое личное убеждение].

Эта служба займет один или два Дао / Репозитория и делегирует ему все постоянные работы:

public class CleverMoneyMakingBusinessService implements MoneyMakingBusinessService {

    private MoneyRepository moneyRepository;

    public void makeMoney( MoneyRoll money )  {
        moneyRepository.make( money );
    }

    public MoneyRoll withdrawMoney( Long moneyRollId ) {
        return moneyRepository.find( moneyRollId );
    }

    public void setMoneyRepository( MoneyRepository moneyRepository ) {
        this.moneyRepository = moneyRepository;
    }
}

Принимая во внимание, что репозиторий / DAO может выглядеть следующим образом (обратите внимание, что он не использует HibernateTemplate, поскольку @Repository выполняет все переводы исключений, а Hibernate SessionFactory может и должен использоваться напрямую) :

@Repository
public class HibernateMoneyRepository implements MoneyRepository {

    private SessionFactory sessionFactory;

    public MoneyRoll find( Long rollId ) {

        MoneyRoll moneyRoll = null;

        Query query = getSession().getNamedQuery("find.moneyroll.by.id");
        query.setParameter( "id", rollId );

        List<MoneyRoll> moneyList = query.list();

        if ( moneyList.size() != 0 ) {
            moneyRoll = ( MoneyRoll )query.list().get( 0 );
        }

        return moneyRoll;
    }

    public void make( MoneyRoll moneyRoll ) {
        getSession().save( moneyRoll );
    }

    public void takeOut( MoneyRoll moneyRoll ) {
        getSession().delete( moneyRoll );
    }

    public void update(MoneyRoll money) {

        Query query = getSession().getNamedQuery("update.moneyroll");
        query.setParameter( "id", money.getId() );
        query.setParameter( "amount", money.getAmount() );
        query.setParameter( "currency", money.getCurrency() );

        query.executeUpdate();
    }

    private Session getSession() {
        return sessionFactory.getCurrentSession();
    }

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }   
}

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

0 голосов
/ 12 октября 2011

Используйте Spring для управления своими транзакциями (я вижу это как один из ваших тегов).

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

Один из относительно простых способов сделать это - настроить Spring, чтобы сделать все методы обслуживания транзакционными, но вы не ограничены этим - вы можете сделать это настолько простым или сложным, насколько захотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...