Как зафиксировать текущий guice-persist UnitOfWork? - PullRequest
1 голос
/ 08 февраля 2012

Я использую UnitOfWork в методе фоновой задачи (управляемом Quartz) с Guice-persist поверх hibernate.Фоновая задача вызывает службу, которая должна зафиксировать текущую транзакцию в середине своей задачи и продолжить другую транзакцию.Как я могу зафиксировать текущий UnitOfWork и создать новый?

class BackgroundJob {
    @Inject UnitOfWork unitOfWork;
    @Inject MyService myService;
    public void run() {
        try {
            unitOfWork.begin();
            myService.foo();
        } finally {
            unitOfWork.end();
}   }   }

class MyServiceImpl implements MyService {
    @Override public void foo() {
        foo1();
        // I would like to commit here and start a new transaction
        foo2();
}   }

Служба также управляется Guice, но является одноэлементной и не имеет доступа к вызывающему UnitOfWork какis .

В идеале я не хочу менять подпись сервиса.Обходной путь для вызывающего абонента состоит в том, чтобы дать два UnitOfWork в качестве параметров foo(), но это кажется немного взломанным.моя реализация решения, предоставленного ColinD, которое прекрасно отвечает всем требованиям:

class BackgroundJob {
    @Inject UnitOfWork unitOfWork;
    @Inject MyService myService;
    public void run() {
        try {
            unitOfWork.begin();
            myService.foo();
        } finally {
            unitOfWork.end();
}   }   }

class MyServiceImpl implements MyService {
    @Override public void foo() {
        foo1();
        foo2();
    }
    @Transactional private void foo1() { ... }
    @Transactional private void foo2() { ... }
}

Ответы [ 2 ]

4 голосов
/ 09 февраля 2012

Если я правильно помню, единица работы в Guice Persist - это , а не отдельная транзакция.Скорее, он представляет собой единицу работы, такую ​​как один веб-запрос или, в вашем случае, одну фоновую работу.Я считаю, что одно соединение с базой данных используется для целой единицы работы, но эта единица работы может иметь несколько различных транзакций.На самом деле, я думаю, что только начало и окончание единицы работы не приведет к запуску или завершению каких-либо транзакций.

Я думаю, что вы хотите сделать, это аннотировать как foo1(), так и foo2() (но не foo()) с @Transactional.Пока нет внешней транзакции, заключающей в себе оба вызова, каждый из них будет выполняться в отдельной транзакции.

0 голосов
/ 08 февраля 2012

Это может соответствовать всем требованиям.

class BackgroundJob {
    @Inject UnitOfWork unitOfWork;
    @Inject MyService myService;

    public void run() {
        try {
            unitOfWork.begin();
            myService.foo1();
            unitOfWork.end();
           unitOfWork.begin();
            myService.foo2();
            unitOfWork.end();
        } finally {
            unitOfWork.end();
        }
    }
}
...