Spring 数据处理中的事务级别

在 Spring 项目中,如果使用了 Spring 的事务管理的话。

默认的事务级别都在类,这个级别的,这就导致了,如果在循环中对数据进行处理的话,如果循环不结束,事务是不会提交的。

如果出现了事务堆积的情况,大概率就会锁表,然后整个服务抛出异常。

如下面的代码:

    public void assignMlsListingUid() {
        List<MlsListing> mlsListingList = mlsListingRepository.findAllByUidIsNull();

        // Loop MlsListing to get UID assigned
        for (MlsListing mlsListing : mlsListingList) {

            try {
                MlsListingCtx mlsListingCtx = ListingUtils.listingDeserialization(mlsListing.getMlsCtx());

                String uid = mlsListing.getUid();
                String addressOneLine = mlsListingCtx.getAddress().getAddressOneLine();

                Listing listing = listingRepository.findDistinctFirstByAddressOneLineEqualsIgnoreCase(addressOneLine);

                if (ObjectUtils.isNotEmpty(listing)) {
                    uid = listing.getUid();
                } else {
                    uid = UUID.randomUUID().toString();
                    listing = new Listing();
                    listing.setAddressOneLine(addressOneLine);
                    listing.setUid(uid);
                    listing.setDateCreate(new Date());
                    listing.setDateUpdate(new Date());

                    listingRepository.save(listing);
                }

                mlsListing.setUid(uid);
                mlsListing.setDateUpdate(new Date());
                mlsListingRepository.save(mlsListing);

            } catch (JsonProcessingException e) {
                log.error("Parse Mls-Listing Ctx Error", e);
                mlsListingRepository.delete(mlsListing);
            }

        }

    }

这个方法,在循环执行完成之前是不会提交事务的。

上面的代码只要部署到服务器上,一旦需要处理的量稍微大一点点,肯定锁表。

解决办法

解决办法就是把循环从 Services 层中拿出来。

放到另外一层,这样的话就能够在循环中进行提交。