Spring两个服务具有相同的Transaction?

时间:2016-07-01 07:42:33

标签: spring hibernate service transactional

我用@Service创建了一些spring服务,并将它们标记为@Transactional。这是按预期工作的。

现在我创建了一个执行谷歌地图请求的小帮助服务。我已经删除了@Transaction注释,认为服务中的函数正在使用相同的事务。

@Transactional
@Service("hourService")
public class HourServiceImpl extends HourService {

    private void updateLogbook(Hour hour) {

        Logbook logbook = getLogbook(hour);

        if (logbook != null) {

            try {

                List<String> locations = logbook.getHours().stream().sorted((t1, t2) -> t1.getStartTime().compareTo(t2.getStartTime())).filter(h -> !h.equals(hour)).map(Hour::getClient).map(Client::getAddress).collect(Collectors.toList());
                locations.add(hour.getClient().getAddress());

                String origin = getOrigin();
                Double distance = mapService.getDistance(origin, origin, locations);

                logbook.add(hour);
                logbook.setProtect(true);
                logbook.setDate(hour.getDate());
                logbook.setDistance(distance / 1000.0);
                logbook.setComment(getComment(logbook.getHours()));

                logbookDao.update(logbook);

            } catch (Exception e) {
                logbook.remove(hour);
                log.error("Failed to update Logbook Entry!", e);
            }

        }

    }

}

和mapService

@Service("mapService")
public class MapServiceImpl extends MapService {

    Logger log = LogManager.getLogger();

    @Autowired
    private Environment environment;

    @Override
    public Double getDistance(String origin, String destination, List<String> waypoints) throws Exception {
        return sendDistanceRequest(origin, destination, waypoints.toArray(new String[waypoints.size()]));
    }

    private Double sendDistanceRequest(String origin, String destination, String... waypoints) throws Exception {

        GeoApiContext context = new GeoApiContext().setApiKey(environment.getRequiredProperty("invoice.maps.key"));
        DirectionsApiRequest request = DirectionsApi.newRequest(context);
        request.mode(TravelMode.DRIVING);

        request.origin(origin);
        request.destination(destination);
        request.waypoints(waypoints);

        try {

            log.info(String.format("Trying to get Distance for %s -> %s -> %s", origin, String.join(" -> ", waypoints), destination));
            DirectionsResult result = request.await();
            if (result.routes.length > 0 && result.routes[0].legs.length > 0) {

                Double distance = 0d;

                for (DirectionsLeg leg : result.routes[0].legs) {
                    distance += leg.distance.inMeters;
                }

                return distance;

            }

        } catch (Exception e) {
            log.error("Failed to get maps response!", e);
        }

        throw new Exception(String.format("Something wrong with this route ... ORIGIN: %s, VIAS: %s, DEST: %s", origin, String.join("|", waypoints), destination));

    }

}

现在我的问题是,调用mapService.getDistance(origin, origin, locations);会给我一个org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: ...Logbook

这可以解释,因为日志实体没有保存,而且hibernate试图提交修改后的Hour实体......但是为什么会提交?它应该使用相同的交易!?!?!?

编辑1

我的问题与mapService无关。问题是getOrigin()正在使用我的settingDao来获取设置值。此调用提交当前事务并使用另一个事务来选择设置值。

所以问题是如何使用相同或嵌套?

0 个答案:

没有答案