2011-12-23 4 views
6

ситуация выглядит следующим образом:Spring сделки внутренности

  1. Method1 имеет четыре способа обновления базы данных в нем. Метод 1 аннотируется с использованием семантики управления транзакциями Spring.

  2. У метода2 есть метод чтения базы данных, и он вызывается после того, как Method1 завершил выполнение всех своих обновлений базы данных. Метод2 также аннотируется с использованием семантики транзакций Spring.

  3. Входит веб-запрос, контроллер перехватывает запрос и вызывает метод1, а затем метод2.

  4. Сделка завернута в веб-запрос.

Что я интересно знать, является:

1.How делает Spring знать, чтобы совершать обновления базы данных после успешной сделки? Есть ли какая-то ссылка на реализацию Spring, которая выполняет управление транзакциями?

2. Поскольку у нас есть иерархия транзакций: Транзакция через веб-запрос-> Транзакция с распространением = ЗапросНовый метод1-> Транзакция с расширением = Требуется для метода2, как Spring управляет транзакциями, чтобы обеспечить транзакции выполняются в правильном контексте с правильным порядком?

Короче говоря, будет здорово получить игру, проигранную игровой учетной записью, о том, как Spring выполняет управление транзакциями во всех своих хрупких подробностях или ссылку на документацию, которая не просто передает волну объяснений, сосредоточенных вокруг JTA, или некоторых другой акроним.

Благодаря

ответ

7

Давайте сделаем несколько основных заявлений.

  1. Контекстный контекст - это среда, в которой некоторые особые свойства (сеанс базы данных) становятся доступными для среды выполнения приложения, которые в противном случае недоступны. Контекст транзакции обычно используется для охвата транзакции.
  2. Spring использует AOP Proxies и XML-метаданные для достижения декларативного управления транзакциями.
  3. Аннотации используются для обозначения поведения распространения транзакций определенного метода.
  4. Spring использует Interceptor Mechanism для применения транзакции по методам.

Здесь я повторно использовать пример дают по @stacker выше

MyClass{ 

    @Transactional 
    public void sequence() { 
     method1(); 
     method2(); 
    } 

    @Transactional 
    void method1() { 
    } 

    @Transactional(propagation=Propagation.REQUIRES_NEW) 
    void method2() { 
    } 

} 

Вы также можете достичь того же функциональность с помощью конфигурации XML, а также. Давайте считать это популярным и широко используемым.

Во время развертывания

  • Spring Framework проверяет файлы конфигурации XML (Прославленный applicationContext.xml) и в зависимости от конфигурации, сканирует код @Transactional аннотацию (при условии, что конфигурация упоминается как аннотацию на основе).
  • После этого он создает AOP прокси для методов, обозначенных для транзакции. Проще говоря, эти прокси-серверы - это не что иное, как обертка вокруг соответствующих методов.
  • Внутри этих методов обёртки до и после Код транзакции также генерируется в зависимости от конфигурации (а именно, распространения транзакции).
  • Теперь, когда вызывается эти методы обёртки Советник по транзакциям входит в изображение до и после фактического вызова метода. ,
  • Представляя то же самое в псевдокоде для приведенного выше примера

    ProxyMyClass{ 
        MyClass myclass; 
        . 
        . 
        . 
        sequence(){ 
        //Transaction Advisor code (Typically begin/check for transaction) 
        myclass.sequence(); 
        //Transaction Advisor code(Typically rollback/commit) 
        } 
        . 
        . 
        . 
        } 
    

Вот как пружинные менеджеры сделки. Однако небольшое упрощение.

Теперь, чтобы ответить на ваши вопросы,

.Как делает Spring знать, чтобы совершать обновления базы данных после успешной сделки? Есть ли какая-то ссылка на реализацию Spring, которая выполняет управление транзакциями?

Когда вы вызываете метод под транзакцией, вы фактически вызываете прокси-сервер, который сначала выполняет советник транзакции (который начнет транзакцию), а затем вы вызываете фактический бизнес-метод, после завершения которого выполняется другой советник по транзакциям в зависимости от способа возврата метода, транзакции фиксации или возврата).

Поскольку у нас есть иерархия транзакций: транзакция вокруг веб-запроса-> транзакция с распространением = запросNew для метода1-> транзакция с распространением = требуется для метода2, как Spring управляет транзакциями, чтобы гарантировать, что транзакции выполняется в правильном контексте с правильным порядком?

В случае иерархии транзакций весенний фреймворк соответственно генерирует советник по транзакциям. Например, вы упомянули,

  • для метода1 (RequestNew) Код транзакции для транзакции (или консультация по сделке) заключался бы в том, чтобы всегда создавать новую транзакцию.
  • для метода2 (обязательно) Код консультанта транзакции (или консультация по транзакции) будет проверять существующую транзакцию и использовать ее, если она существует, или создать новую транзакцию.

Существует image on the spring documentation page, который очень красиво суммирует эти аспекты.

Typical Spring Transaction Management

Надеется, что это помогает.

+0

Это было невероятное объяснение. Спасибо –

+0

Можете ли вы объяснить, если на диаграмме выше вызывающий абонент является контроллером или веб-запросом? – tintin

+0

@tintin, не имеет значения, является ли вызывающий контроллер или что-то еще. В конце это будет вызов метода от некоторого класса к прокси. – Santosh

4
Controller 
@Transactional 
public void sequence() { 
    method1(); 
    method2(); 
} 

@Transactional 
void method1() { 
} 

@Transactional(propagation=Propagation.REQUIRES_NEW) 
void method2() { 
} 

распространения по умолчанию НЕОБХОДИМЫЕ (Поддержка текущей транзакции, создать новый, если он не существует.) Поэтому m1 будет использовать Операцию начали в контроллере. m2 аннотируется как REQUIRES_NEW (создайте новую транзакцию, приостановите текущую транзакцию, если она существует.) Порядок транзакции - это порядок, который вы называете транзакционными методами.

Controller 
begin tx1 
    |--------------------> m1 (uses tx1) 
    | 
    | begin tx2 
    |--------------------> m2 (uses tx2) 
    | commit tx2 
commit tx1 
+0

В типичной среде MVC транзакция начинается с уровня контроллера? или он запускается при обслуживании с помощью аннотации @Transactional, которую вызывает контроллер? – tintin

+0

@tintin Если у вас есть услуги «низкого уровня», вы можете комбинировать их с разными транзакциями (для разных действий), поэтому вы должны начать транзакции в своем контроллере. Метод, аннотированный транзакцией, присоединяется к существующей транзакции (например, (начатый в контроллере)) – stacker

0

Вы прочитали Spring documentation? В основном АОП используется для управления транзакцией. Вы также должны прочитать AOP documentation. Если документации AOP недостаточно, я предлагаю вам пройти через код. Было бы хорошо проделать код в режиме отладки с точкой останова.