Что делает транзакцию транзакцией в Spring / Java (конкретный сценарий)? - PullRequest
0 голосов
/ 16 января 2012

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

У меня есть класс BuyService, который является транзакционным.Класс BuyService объявлен транзакционным, и его единственный метод - buyWidget (String widgetId).Этот метод вызывает класс ExampleService, у которого есть метод deleteWidgit (String widgetId).Он также вызывает класс InvoiceService, который использует метод writeInvoice (String widgitId).Вот код:

Класс BuyService:

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Transactional
public class BuyService implements BuyServiceInterface
{
private ExampleServiceInterface exampleService;
private InvoiceServiceInterface invoiceService;

public void setExampleService(ExampleServiceInterface exampleService)
{
    this.exampleService = exampleService;
}

public void setInvoiceService(InvoiceServiceInterface invoiceService)
{
    this.invoiceService = invoiceService;
}

@Override
@Transactional(propagation=Propagation.REQUIRED)
public void buyWidget(Widget widgetId)
{
    try
    {
        Widget purchasedWidget = this.exampleService.getWidgetById(String widgetId);
        this.exampleService.deleteWidget(purchasedWidget);
        this.invoiceService.writeInvoice(purchasedWidget);
    }
    catch (WidgetNotFoundException e)
    {
        System.out.println("Widget with widgetId " + widgetId + " not found.");
    }
}
}

Я почти уверен, что метод buyWidget представляет собой транзакцию.Это требует удаления виджета в базе данных (в exampleService) и вставки данных в базу данных покупки (в invoiceService).Но я запутался в терминологии после этого момента.Методы deleteWidget и writeInvoice тоже являются транзакциями?

Класс ExampleService:

public class ExampleService implements ExampleServiceInterface
    {   
private ExampleServiceDaoInterface dao;

public void setExampleServiceDao(ExampleServiceDaoInterface dao)
{
    this.dao = dao;
}

@Override
public void deleteWidget(Widget oldWidget) 
        throws WidgetNotFoundException
{
    this.dao.delete(oldWidget);
}

@Override
public Widget getWidgetById(String widgetId)
{
    return this.dao.getById(widgetId);
}
}

Класс InvoiceService:

public class InvoiceService implements InvoiceServiceInterface
{   
private InvoiceServiceDaoInterface InvoiceServiceDao;

public void setInvoiceServiceDao(InvoiceServiceDaoInterface InvoiceServiceDao)
{
    this.InvoiceServiceDao = InvoiceServiceDao;
}

@Override
public void writeInvoice(Widget purchasedWidget)
{
    Date purchaseDate = new Date(new java.util.Date().getTime());
    String isbn = purchasedWidget.getIsbn();
    Purchases newPurchase = new Purchases(purchaseDate, isbn);
    this.InvoiceServiceDao.savePurchase(newPurchase);
}
} 

Являются ли эти два метода также вызываемыми транзакциями buyWidget?То есть, даже если ни один из этих методов не объявлен как транзакция.Каковы некоторые потенциальные ловушки, не позволяющие объявить два дочерних метода транзакциями?(Поскольку они, по-видимому, уже являются частью одного).

Ответы [ 2 ]

3 голосов
/ 16 января 2012

Являются ли методы deleteWidget и writeInvoice самими транзакциями?

Они будут участвовать в транзакции buyWidget, но сами по себе они не являются транзакциями

Являются ли эти два метода также вызванными транзакциями buyWidget?

Транзакция начинается до входа в метод buyWidget и останавливается или откатывается до завершения метода. Оба метода будут участвовать в транзакции buyWidget, но сами не являются транзакциями.

1 голос
/ 16 января 2012

Являются ли эти два метода также вызванными транзакциями buyWidget?

Ни один из методов не является транзакциями. Аннотация @Transactional(propagation=Propagation.REQUIRED) означает «Поддерживать текущую транзакцию, создать новую, если ее не существует». Эта транзакция будет включать все, что вызывается из метода buyWidget(). В основном, когда метод вводится, транзакция запускается, и когда он завершается, эта транзакция будет зафиксирована (если все получится) или откатится (если возникнет исключение, возникнет проблема на стороне БД или транзакция будет отменена). обратно через код Java).

То есть, даже если ни один из этих методов не объявлен как транзакция.

Пока эти методы работают с БД, которая знает о JTA, она будет работать с существующей транзакцией.

Каковы некоторые потенциальные ловушки, не позволяющие объявить два дочерних метода транзакциями? (Поскольку они, видимо, уже являются частью одного)

Если эти методы вызываются напрямую, они не будут частью транзакции. Это может привести к несовместимому состоянию БД, если эти методы приводят к нескольким операторам SQL (это не выглядит так, но нельзя определенно исключить это, просто взглянув на код).

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