Весенняя загрузка 2 данных JPA: транзакция не откат [дубликат]

Ваша проблема, похоже, сводится к выбору k элементов случайным образом из набора из n элементов. Таким образом, запрос Collections.shuffle является правильным, но, как указано, неэффективен: его O (n).

Википедия: Fisher-Yates shuffle имеет версию O (k), когда массив уже существует. В вашем случае нет массива элементов, и создание массива элементов может быть очень дорогостоящим, скажем, если max было 10000000 вместо 20.

Алгоритм тасования включает инициализацию массива размера n, где каждый элемент равен его индексу, подбирая k случайных чисел каждое число в диапазоне с максимальным, меньшим, чем предыдущий диапазон, затем заменяя элементы на конец массива.

Вы можете сделать ту же операцию в O (k) время с помощью hashmap, хотя я признаю ее вид боли. Заметим, что это стоит того, если k намного меньше n. (т. е. k ~ lg (n) или так), в противном случае вы должны использовать тасование напрямую.

Вы будете использовать свой хэш-карту как эффективное представление массива поддержки в алгоритме тасования. Любой элемент массива, который равен его индексу, не должен появляться на карте. Это позволяет вам представлять массив размера n в постоянное время, нет времени, затрачиваемого на его инициализацию.

  1. Выберите k случайных чисел: первый находится в диапазоне от 0 до n-1, второй от 0 до n-2, третий от 0 до n-3 и т. д., через n-k.
  2. Рассматривайте свои случайные числа как набор свопов. Первый случайный индекс переходит в конечную позицию. Второй случайный индекс свопит во вторую и последнюю позицию. Однако вместо того, чтобы работать с массивом поддержки, работайте против вашего хэшмапа. Ваш хэш-файл сохранит все позиции, которые находятся вне позиции.

int getValue(i) { if (map.contains(i)) return map[i]; return i; } void setValue(i, val) { if (i == val) map.remove(i); else map[i] = val; } int[] chooseK(int n, int k) { for (int i = 0; i < k; i++) { int randomIndex = nextRandom(0, n - i); //(n - i is exclusive) int desiredIndex = n-i-1; int valAtRandom = getValue(randomIndex); int valAtDesired = getValue(desiredIndex); setValue(desiredIndex, valAtRandom); setValue(randomIndex, valAtDesired); } int[] output = new int[k]; for (int i = 0; i < k; i++) { output[i] = (getValue(n-i-1)); } return output; }

0
задан abiieez 13 December 2015 в 13:04
поделиться

1 ответ

Проблема связана с движком таблицы, который MyISAM. Транзакция способна откат после того, как я изменил движок на InnoDB.

Настройка hibernate.dialect на org.hibernate.dialect.MySQLInnoDBDialect гарантирует создание таблицы с InnoDB в будущем.

0
ответ дан abiieez 16 August 2018 в 04:59
поделиться
Другие вопросы по тегам:

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