простая вставка mysql при весенней загрузке дает исключение lockAquision и как правильно выполнить массовую вставку - PullRequest
0 голосов
/ 18 октября 2019

Я работаю с Spring boot с сервером mysql. У меня есть запланированный метод, который удаляет записи (тысячи), а затем вставляет (тысячи) записей. Обе операции массового удаления + вставки выполняются внутри транзакции.

Вот код:

@Service
public class BulkInsert
{

    public static final String DELETE_ALL_ROWS_QUERY = "DELETE FROM GnsEntity where is_synced = true and was_removed = false";

    @Inject
    private EntityManager entityManager;

    @Transactional
    public void save(List<GnsEntity> gnsEntityList)
    {
        Session session = entityManager.unwrap(Session.class);
        Query entity = session.createQuery(DELETE_ALL_ROWS_QUERY);
        entity.executeUpdate();
        for (int i = 0; i < gnsEntityList.size(); ++i)
        {
            try
            {
                session.save(gnsEntityList.get(i));
            }
            catch(NonUniqueObjectException nonUniEx)
            {

            }
        }
    }
}

Запланированный аннотированный код метода:

@Log4j
@Component
public class PeriodicDataSynchornizer
{

    @Inject
    private LdapService m_ldapService;

    @Inject
    private BulkInsert m_bulkInsert;

    @Inject
    private RestTemplate restTemplate;


    @Scheduled(fixedDelayString = "#{  60000*${swiss.GNSSynchronizer.rateMin}}")
    public void run()
    {
        log.info("starting syncing process");
        List<GnsEntity> allowedPaths = null;
        try
        {
            allowedPaths = m_ldapService.dumpAllowedPaths();
            allowedPaths.addAll(m_ldapService.dumpAllGnsPathHistory());
        }
        catch (NamingException e)
        {
            log.info("caught NamingException from LdapService",e);
            return;
        }
        log.info("got " + allowedPaths.size() + "elements from GNS database");
        m_bulkInsert.save(allowedPaths);
        log.info("finished syncing");
    }

}

Этот метод Schedule выполняется каждые 2-3 минуты и единственный, который обращается к БД.

Я пытаюсь понять, что я получаю следующее исключение много раз:

{"@timestamp ":" 2019-10-18T19: 28: 39.851Z "," logLevel ":" WARN "," message ":" Ошибка SQL: 1213, SQLState: 40001 "," service ":" GNSSynchronizer "," instanceId":" 1" , "приложение": "MyApp", "пространство": "MySpace", "класс": "org.hibernate.engine.jdbc.spi.SqlExceptionHelper", "нить": "бассейн-3-жильный-1 "," X-B3-TraceId ":" 5daa1244ee26ba17344882356d926d42 "," X-B3-Spa nId ":" 344882356d926d42 "} {" @timestamp ":" 2019-10-18T19: 28: 39.851Z "," logLevel":" ОШИБКА "," message ":" Обнаружена тупиковая ситуация при попытке получить блокировку; попробуйте перезапустить транзакцию "," service ":" GNSSynchronizer "," instanceId ":" 1 "," application ":" myapp "," space":" mysapce " "класс":" org.hibernate.engine.jdbc.spi.SqlExceptionHelper "," thread ":" pool-3-thread-1 "," X-B3-TraceId ":" 5daa1244 ee26ba17344882356d926d42 "," X-B3-SpanId ":" 344882356d926d42 "}

Почему это происходит? Как я могу отладить это?

В будущем также будет другая служба, которая будет читать все записи - как мне убедиться, что она не будет ждать окончания удаления + вставки? это mvv - поведение mysql по умолчанию?

Кроме того, я пытаюсь сделать эту операцию sql для массового запуска.

У меня есть это свойство spring: spring.jpa.properties. hibernate.jdbc.batch_size = 20

, а в URL-адресе соединения есть "rewriteBatchedStatemen = true", но вы все равно вставляете в журнал все вставки одну за другой:

  /* insert com.a.b.microservices.gnssynchronizer.GnsEntity
        */ insert 
        into
            gns_entity
            (changer, comments, description, dir_type, history_rec, is_synced, owner, status, submitter, was_removed, path, update_time) 
        values
            (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: 
    /* insert com.a.b.microservices.gnssynchronizer.GnsEntity
        */ insert 
        into
            gns_entity
            (changer, comments, description, dir_type, history_rec, is_synced, owner, status, submitter, was_removed, path, update_time) 
        values
            (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

вместо всех вместе водно большое sql заявление.

Спасибо за вашу помощь!

...