Предел стола Джека?

В настоящее время я пытаюсь решить проблему, связанную с программой, написанной кем-то другим, которая использует Jackcess версии 1.1.8 для записи информации в базу данных Access. В прогоне, который должен добавить 4 миллиона строк в данную таблицу Access, возникает следующее исключение:

08/29/2016 06:01:47 | ERROR | java.lang.IndexOutOfBoundsException
at java.nio.Buffer.checkIndex(Unknown Source)
at java.nio.HeapByteBuffer.getInt(Unknown Source)
at com.healthmarketscience.jackcess.ReferenceUsageMap.addOrRemovePageNumber(ReferenceUsageMap.java:82)
at com.healthmarketscience.jackcess.UsageMap.addPageNumber(UsageMap.java:201)
at com.healthmarketscience.jackcess.Table.newDataPage(Table.java:761)
at com.healthmarketscience.jackcess.Table.addRows(Table.java:714)
at com.healthmarketscience.jackcess.Table.addRow(Table.java:660)

Из того, что я видел в Интернете, похоже, что текущая версия Jackcess - 2. *, так что это то, что можно решить с помощью последней версии, или есть более серьезная проблема, например, на 4 миллиона строк слишком много для таблицы доступа? В качестве альтернативы, есть ли способ добавить строки через объект Cursor, который потребовал бы меньше памяти?


person Sheldon R.    schedule 30.08.2016    source источник
comment
Нет, 4 миллиона - это не слишком много строк для таблицы Access как таковой. Однако, если размер файла базы данных превышает ограничение в 2 ГБ, это может вызвать проблемы. Что касается чего-то менее ресурсоемкого, исключение не указывает на проблему с памятью JVM (например, нехватку места в куче). Создает ли это приложение новый файл базы данных или записывает в существующий?   -  person Gord Thompson    schedule 30.08.2016
comment
@GordThompson, рассматриваемый код создает объект Table, а затем вызывает его метод addRow (), поэтому я предполагаю, что объект Table слишком велик в какой-то момент, чтобы поместиться в памяти, отсюда и исключение ...   -  person Sheldon R.    schedule 30.08.2016


Ответы (1)


Если рассматриваемое приложение по-прежнему важно для вашего бизнеса, вам необходимо обновить его, чтобы использовать текущую версию Jackcess. Вы получили от этого более 9 лет (Jackcess 1.1.8 был выпущен в феврале 2007 года), и с тех пор дела пошли немного вперед.

Примечательно, что текущая версия Jackcess поддерживает DatabaseBuilder#setAutoSync(false), который отключает построчную очистку обновлений файла базы данных. (Я искал в исходном коде Jackcess 1.1.8 слово «autosync» и не нашел совпадений, поэтому предполагаю, что тогда он не поддерживался.)

Для тестовой вставки 100 000 строк с использованием Jackcess 2.1.3, setAutoSync(true) (по умолчанию) потребовалось около 200 секунд, в то время как тот же код с setAutoSync(false) занял 8 секунд.

Тестовая вставка 4 000 000 строк с setAutoSync(false) заняла около 220 секунд, или чуть более 3,5 минут. Исходя из приведенных выше цифр, можно ожидать, что та же операция без setAutoSync(false) займет порядка 5 500 секунд, или 1,5 ЧАСА, чтобы выполнить то же самое.

person Gord Thompson    schedule 31.08.2016
comment
В свете предыдущего разговора с другим комментатором, я ценю мягкий характер вашего ответа, @GordThompson :) Отключение автосинхронизации может помочь с другой проблемой, о которой я говорил только косвенно: медлительность этого приложения. Для создания таблицы с 4 миллионами строк программа выполнялась четыре дня до сбоя. Основываясь на результатах ваших тестов, дающих время выполнения, которое в 25 раз лучше, чем для режима по умолчанию, эта программа должна завершиться за часы, а не дни. Буду держать вас в курсе ... - person Sheldon R.; 31.08.2016
comment
Я обновил программу, чтобы использовать последнюю версию Jackcess, и хорошей новостью является то, что она работала за 14 минут вместо четырех дней. Но плохая новость в том, что он все равно вышел из строя. Но, по крайней мере, он был более информативным о том, в чем проблема: предел размера 2G для баз данных Access был достигнут. Я видел на веб-сайте MS-Access, что таблицы могут быть связаны из одной базы данных в другую. Вы случайно не знаете, позволяет ли вам это Jackcess? - person Sheldon R.; 31.08.2016
comment
Да, Jackcess может работать с базой данных, содержащей таблицы, связанные с таблицами в другой базе данных Access, и в Windows это довольно прозрачно. (На машинах, отличных от Windows, нам нужно создать класс, реализующий LinkResolver для согласования пути Windows в ссылке на таблицу с путем, отличным от Windows.) Я не помню, чтобы видел в Jackcess механизм для create ссылку на таблицу в базе данных, но обходным путем для этого было бы создать базу данных шаблона в Access с необходимыми ссылками на таблицы и начать с нее вместо совершенно нового пустого файла базы данных. - person Gord Thompson; 01.09.2016