В чем разница открытия многопоточности между сервисом и контроллером? Когда я открываю multiThreading в контроллере, мне не нужно открывать сеанс гибернации, и я могу получить currentSession
. Но когда я открываю поток в службе, я должен сначала получить hibernate sessionFactory, а затем открыть новый сеанс. И в конце я должен закрыть сеанс. Пожалуйста, помогите или попытайтесь дать несколько идей, как этого добиться.
@Controller
public class TestController extends BaseController {
@Autowired
private TestService testService;
@Autowired
private ThreadPoolTaskExecutor taskExecutor;
@Autowired
private TestDao testDao;
@ResponseBody
@RequestMapping("/testMultiInService")
public Object test() {
GenericListResponse response = testService.testMulti();
return response;
}
}
@Service
public class TestServiceImpl extends TestService {
@Autowired
private ThreadPoolTaskExecutor taskExecutor;
@Autowired
private TestDao testDao;
private static Logger logger = Logger.getLogger(TestServiceImpl.class);
@Override
@Transactional
public GenericListResponse testMulti() {
CountDownLatch latch = new CountDownLatch(2);
TestCallable1 callable1 = new TestCallable1(this, latch);
Future<List> future1 = taskExecutor.submit(callable1);
List list = new ArrayList();
try {
latch.await();
if (null != future1)
list.addAll(future1.get());
if (null != future2)
list.addAll(future2.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class TestCallable1 implements Callable<List> {
private TestService testService;
private CountDownLatch latch;
public TestCallable1(TestService testService, CountDownLatch latch) {
this.testService = testService;
this.latch = latch;
}
@Override
public List call() throws Exception {
List list = null;
try {
list = testService.getDimArea();
} catch (Exception e) {
e.printStackTrace();
} finally {
this.latch.countDown();
return list;
}
}
}
Это всего лишь фрагмент кода для тестирования, и вопрос в том, в чем разница, открывающая многопоточность между сервисом и контроллером. Открывая multiThread в контроллере, нам не нужен открытый сеанс гибернации. Мы не можем получить текущий сеанс. Но в сервисе мы должны открыть новый сеанс и закрыть его в конце. Это слишком хлопотно. Как решить эту проблему. ? У вас есть другие решения лучше? Спасибо.
вы на самом деле выполняете какую-либо логику гибернации в своем будущем? Транзакционная аннотация открывает для вас сеанс, но этот сеанс, вероятно, недоступен в ваших будущих объектах, выполняемых потоком-исполнителем, это то, что вы говорите? ЕСЛИ вы хотите иметь его в той же службе, вы можете создать нетранзакционный метод и вызывать транзакционные методы для своих фьючерсов. Если вы вызываете метод напрямую, он не будет создавать транзакцию, поскольку он будет обходить прокси, но вы можете ввести ту же службу с аннотацией Autowired и получить прокси для использования
Ты прав. Теперь я нашел способ решить эту проблему. Прежде чем открыть поток в службе, а метод, вызываемый в вызываемом классе, является той же службой, использовать прокси-сервер бесполезно. Теперь я создаю другую службу. для метода, вызываемого в вызываемом с транзакцией. Он работает. Спасибо за напоминание.
Кроме того, не могли бы вы дать несколько советов о том, как изучить новую технологию. Официальный документ завершает так много вопросов, и как мне исходить из них? Или другие эффективные способы обучения. Пожалуйста, помогите человеку, который хочет улучшить свои навыки.
зависит от того, чему вы хотите научиться. Обычно я хочу учиться на собственном примере, а потом делать то же самое сам. Просто читать документацию не для меня :)
Вы правы, это важно для совмещения теории с практикой, где вы обычно находите примеры?
google и stackoverflow, просто нужно читать, а не слепо копировать вставку :)
Так много точек в документе. Как вы находите важное или обычное для чтения, изучения и практики?
Не могли бы вы описать, в чем проблема? И почему вы используете обратный отсчет с пулом потоков-исполнителей? Какая логика вам нужна?