powered by simpleCommunicator - 2.0.30     © 2024 Programmizd 02
Map
Форумы / Java [игнор отключен] [закрыт для гостей] / Mybatis+PostgreSQL паралелльные потоки
25 сообщений из 115, страница 1 из 5
Mybatis+PostgreSQL паралелльные потоки
    #39892134
qi_ip
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Приветствую! Использую связку myBatis и PostgreSQL.

Приложение делает инсерт в таблицу [table1], вызывает метод push() и параллельный поток делает селект из этой же таблицы [table1] и обрабатывает полученные записи для дальнейшего анализирования.
myBatis использует пул потоков к PostgreSQL. В какой-то момент, получается так, что инсерт и селект происходят почти в одно и то же время (разница 0.002 мс) и селект не видит новых записей.

Код инсерта:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
SqlSession sqlSession = SqlMapHelper.getSqlSessionFactory().openSession(true);
try {
	List<HashMap> messagesMapList = new ArrayList<>();
	for (Long el : messageList) {
		HashMap map = new HashMap();
		map.put("id", UUID);
		map.put("body", "Here example text");
		messagesMapList.add(map);
	}

	sqlSession.insert("insertMessageList", messagesMapList);
	sqlSession.commit();
	push();
} catch (Exception e) {
	sqlSession.rollback();
} finally {
	sqlSession.close();
}



Код селекта:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SqlSession sqlSession = SqlMapHelper.getSqlSessionFactory().openSession(true);
try {
	List<Mess> messageList = sqlSession.selectList("selectMessages");
	for (Mess m : messageList ) {
		parse(m);
	}
} catch (Exception e) {
} finally {
	sqlSession.close();
}



Подскажите, может кто сталкивался, как это разруливается. Пробовал ставить в SqlMapHelper.getSqlSessionFactory().openSession isolation level READ COMMITED, но все равно не видит.

Спасибо!
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892137
mad_nazgul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qi_ip,

Так все правильно!
Разные транзакции.
Транзакция для insert еще не закончилась, а транзакция для select уже началась.

Можно попробовать "грязное чтение", тогда возможно, будет работать как вам надо.
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892147
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qi_ip
как это разруливается.
разве есть ошибка?
Код исправно ПАРАЛЛЕЛЬНО И НЕЗАВИСИМО работает.
Когда то первым будет чтение, когда то вставка.
Вам это не нравится.
В чем проблема?
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892167
qi_ip
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
mad_nazgul
qi_ip,

Так все правильно!
Разные транзакции.
Транзакция для insert еще не закончилась, а транзакция для select уже началась.

Можно попробовать "грязное чтение", тогда возможно, будет работать как вам надо.

Метод push() по коду вызывается уже после того, как произошел sqlSession.commit(); , поэтому теоретически select из другого потока должен (не факт) видеть сохраненную запись? Или я не прав?
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892168
qi_ip
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
PetroNotC Sharp
qi_ip
как это разруливается.
разве есть ошибка?
Код исправно ПАРАЛЛЕЛЬНО И НЕЗАВИСИМО работает.
Когда то первым будет чтение, когда то вставка.
Вам это не нравится.
В чем проблема?

Ну проблема как раз выше описал, что сначала происходит sqlSession.commit(); , потом инициируется метод, где открывается новая транзакция для чтения этой записи, но ее не читает ))) хотя теоретически если commit не fail, то запись уже в БД. Но это только теория...
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892175
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qi_ip
поэтому теоретически select из другого потока должен (не факт) видеть сохраненную запись? Или я не прав?
должен.
Поставь логирование и дай сюда лог.
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892235
mad_nazgul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qi_ip
mad_nazgul
qi_ip,

Так все правильно!
Разные транзакции.
Транзакция для insert еще не закончилась, а транзакция для select уже началась.

Можно попробовать "грязное чтение", тогда возможно, будет работать как вам надо.

Метод push() по коду вызывается уже после того, как произошел sqlSession.commit(); , поэтому теоретически select из другого потока должен (не факт) видеть сохраненную запись? Или я не прав?


Не совсем.
Т.к. взаимодествие асинхронное, то нужно еще время для PostgreSQL, чтобы "закрыть" транзакцию.

Так что что будет и как - фиг его знает. Зависит еще от скорости PostgreSQL.
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892251
Kachalov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qi_ip,
попробуйте использовать одну сессию (если это возможно) и для инсерта и для селекта, т е вот этот код:
Код: java
1.
SqlSession sqlSession = SqlMapHelper.getSqlSessionFactory().openSession(true);


выполняйте только один раз
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892259
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kachalov,
В разных потоках нельзя.
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892272
Kachalov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC Sharp
В разных потоках нельзя.

- почему это? синхронизацию потоков ручками сделать и передавать инстанс SqlSession с комитом при выходе из синхронизированного куска кода
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892276
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А так?
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
SqlSession sqlSession = SqlMapHelper.getSqlSessionFactory().openSession(true);
try {
	List<HashMap> messagesMapList = new ArrayList<>();
	for (Long el : messageList) {
		HashMap map = new HashMap();
		map.put("id", UUID);
		map.put("body", "Here example text");
		messagesMapList.add(map);
	}

	sqlSession.insert("insertMessageList", messagesMapList);
	sqlSession.commit();
	
} catch (Exception e) {
	sqlSession.rollback();
} finally {
	sqlSession.close();
}
push();
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892279
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kachalov,
Да он вообще ошибся со своей ошибкой. Должен быть видно все что закоммичено в другом соединении. А в этом и подавно.
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892280
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kachalov
почему это?

1. Не потокобезопасен ни класс ни драйвер.
2. Можно синронизировать и тормозить БЛ. Зачем тогда параллелили?
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892281
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC Sharp
Kachalov,
Да он вообще ошибся со своей ошибкой. Должен быть видно все что закоммичено в другом соединении. А в этом и подавно.

Вообще зависит от реализации. Хз что commit() делает. Гарантированно данные будут записаны, когда закончится нативная транзакция у Postgres, а вот то что она закнчивается на commit() никто не гарантирует.
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892283
Kachalov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC Sharp
1. Не потокобезопасен ни класс ни драйвер.

- еще раз: синхронизацию сделать самостоятельно
PetroNotC Sharp
2. Можно синронизировать и тормозить БЛ. Зачем тогда параллелили?

- а зачем селект после инсерта? такая бизнес логика
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892285
Kachalov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл ник
Хз что commit() делает. Гарантированно данные будут записаны, когда закончится нативная транзакция у Postgres, а вот то что она закнчивается на commit() никто не гарантирует.

- понятно что там еще кэши есть и у MyBatis, и дальше. Но на уровне кэша MyBatis в одной сессии данные врядли противоречивы
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892289
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kachalov
забыл ник
Хз что commit() делает. Гарантированно данные будут записаны, когда закончится нативная транзакция у Postgres, а вот то что она закнчивается на commit() никто не гарантирует.

- понятно что там еще кэши есть и у MyBatis, и дальше. Но на уровне кэша MyBatis в одной сессии данные врядли противоречивы

Наверное можно, но мне кажется проще правильно написать push - чтобы он уже отрабатывал когда сессия закрылась, тогда не важно будет из какой сессии идет селект
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892291
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qi_ip, современные базы данных оперируют не insert-ами а транзакциями. Транзакция это более общее
понятие. Обычно оно охватывает пакет изменений. Это сделано для того чтобы в сложной системе не было аномалий
типа ты переводил деньги с 1 счета на другой и деньги вдруг внезапно исчезли навсегда.

Тоесть чтение должно быть консистентным по отношению к бизнес-операциям. То о чем ты пишешь это dirty-read.
Это бывает когда работаешь с двоичными файлами.

Если ты хочешь организовать коммуникацию двух java-потоков эффективно (producer-consumer) то надо делать
чтобы продюсер уведомлял консюмера через очереди или JMS о том что он закончил порцию операций и она закоммичена
и с ней можно работать.

Но и даже в таком виде КПД твоей двухпоточной системы будет невысоким т.к. консюмер будет все равно вычитывать
объем инфы чуть больше чем ему надо на самом деле.

Как бороться с этим - я пока не знаю это глубоко архитектурный вопрос и надо понимать что ты делаешь на самом деле.
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892310
Kachalov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
надо делать
чтобы продюсер уведомлял консюмера через очереди или JMS о том что он закончил порцию операций и она закоммичена
и с ней можно работать.

- я так понял, что у ТС парадокс в том, что он примерно так все и сделал: закомитил (на уровне MyBatis), и оповестил что можно читать и тут облом - данных в базе еще нет
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892317
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл ник
PetroNotC Sharp
Kachalov,
Да он вообще ошибся со своей ошибкой. Должен быть видно все что закоммичено в другом соединении. А в этом и подавно.

Вообще зависит от реализации. Хз что commit() делает. Гарантированно данные будут записаны, когда закончится нативная транзакция у Postgres, а вот то что она закнчивается на commit() никто не гарантирует.
конечно.
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892319
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kachalov
а зачем селект после инсерта? такая бизнес логика
я и пишу - Странная логика.
То что нужно делать после не делают в другом потоке.
Пусть логи даст.
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892324
Kachalov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл ник
Kachalov
пропущено...

- понятно что там еще кэши есть и у MyBatis, и дальше. Но на уровне кэша MyBatis в одной сессии данные врядли противоречивы

Наверное можно, но мне кажется проще правильно написать push - чтобы он уже отрабатывал когда сессия закрылась, тогда не важно будет из какой сессии идет селект

- можно теоретически усложнить задачу (чисто гипотетически, чтобы обсудить интересную архитектурную проблему) и предположить что речь идет о двух различных сервисах (допустим у нас SOA). Везде есть свои кэши, буфера, сетевые соединения, но БД общая (транзакции разные, коннекты к ней разные и т д, т е все легитимно). Один сервис пишет в БД, другой читает когда получает извещение через шину сообщений.

Проблема: сообщение о записи через шину приходит раньше, чем данные фактически попадают в БД и становятся доступны для чтения.

Пока вижу принципиально два решения (и оба не очень):

1) читать данные из общего кэша, т е до того как они фактически попали в БД и стали доступны для чтения;

2) проверять доступность данных в БД (тут варианты как, но все кривые) и уже тогда посылать извещение.

Еще идеи?
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892328
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kachalov,
В SOA только второй вариант.
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892329
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kachalov,
Если он читает, а данных нет, значит их нет (с)
И никакой проблемы.
...
Рейтинг: 0 / 0
Mybatis+PostgreSQL паралелльные потоки
    #39892344
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если он их закоммитил и следующая читающая транзакция их не видит значит либо режим изоляции
читающей транзакции таков. Либо нарушена какая-то причинно-следственная связь и читающий
находится в далёком будущем.

Я думаю что старик Эйнштейн с этим не согласится. И я тоже.

Поэтому надо логи. С точностью таймингов до милисекунд и будем разбираться.

Я не работал с SqlMapHelper и не вижу под капотом какие там режими изоляции. Поэтому надо также
чтоб кто-то знающий подтвердил что "оно так". Или "не так".
...
Рейтинг: 0 / 0
25 сообщений из 115, страница 1 из 5
Форумы / Java [игнор отключен] [закрыт для гостей] / Mybatis+PostgreSQL паралелльные потоки
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]