Grails, Вставка большого количества данных с помощью withTransaction приводит к OutOfMemoryError

Вот как я это сделал:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class SwaggerControllerNameAttribute : Attribute
{
    public string ControllerName { get; private set; }

    public SwaggerControllerNameAttribute(string ctrlrName)
    {
        if (string.IsNullOrEmpty(ctrlrName))
        {
            throw new ArgumentNullException("ctrlrName");
        }
        ControllerName = ctrlrName;
    }
}

А затем добавьте следующий код в конфигурацию:

configuration.EnableSwagger(c =>
{
     c.GroupActionsBy(apiDesc =>
     {
          var attribute = apiDesc.GetControllerAndActionAttributes<SwaggerControllerNameAttribute>();
          if (attribute.Any())
          {
               return attribute.First().ControllerName;
          }
          else
          {
               return apiDesc.ActionDescriptor.ControllerDescriptor.ControllerName;
          }
     });        
}

И тогда вы можете сделать это:

[ 112]
12
задан Steve Kuo 10 January 2009 в 20:34
поделиться

2 ответа

Это - распространенная проблема со всеми, в спящем режиме приложения, и она вызывается ростом быть в спящем режиме сессии. Я предполагаю, что консоль чаш Грааля проводит быть в спящем режиме сессию, открытую для Вас похожим способом к 'открытому заседанию в поле зрения' шаблон, что я знаю, что это использует в для нормальных веб-запросов.

Решение состоит в том, чтобы овладеть текущей сессией и очистить ее после каждого пакета. Я не уверен, как Вы овладеваете пружинным бобом с помощью консоли, обычно для контроллеров, или обслуживает Вас, просто объявляют их как участников. Затем можно получить текущую сессию с sessionFactory.getCurrentSession(). Для очистки его, просто звонят session.clear(), или если Вы, что быть выборочным использованием session.evict(Object) для каждого Person объект.

для контроллера/сервиса:

class FooController {
    def sessionFactory

    def doStuff = {
        List batch = new ArrayList()
        for (each person in legacy phone book) {
            // Construct new Grails domain class from legacy phone book person
            Person person = new Person(...)
            batch.add(person)
            if (batch.size() > 500) {
                Person.withTransaction {
                    for (Person p: batch)
                        p.save()
                    batch.clear()
                }
                // clear session here.
                sessionFactory.getCurrentSession().clear();
            }
        }
        // Save any remaining
        for (Person p: batch)
            p.save()
        }
    }
}

Надеюсь, это поможет.

12
ответ дан 2 December 2019 в 05:42
поделиться

Тед Налейд написал отличную запись в блоге об улучшении пакетной производительности. В том числе здесь в качестве справки.

15
ответ дан 2 December 2019 в 05:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: