powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / знатокам spring-а
22 сообщений из 22, страница 1 из 1
знатокам spring-а
    #38137978
LVA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LVA
Гость
Добрый день, в jave новичок, в спринге тем более. Возник такой вопрос: как перенести на spring довольно простой jdbc-код.

Суть в том, что нужно один раз сделать prepare для каждого используемого DML, и затем использовать их в одном соединении с БД для пакетной вставки данных ПОРЦИЯМИ одновременно в несколько таблиц, периодически делая commit , после некоторого количества порций данных (то есть использовать несколько транзакций).

Как в спринге это сделать, не могу пока понять. Есть batchUpdate, но он не дает возможность делать вставку порциями в несколько таблиц (1000 строк в мастер-таблицу, потом соответствующие строки в таблицы деталей, затем коммит, затем снова порция данных в мастер и в детали). Если использовать несколько batchUpdate по отдельности, то нет возможности сделать prepare один раз, и расходуется лишняя память (необходимо подготовить отдельный список с одной порцией).

jdbc-код метода вставки результатов расчета в БД примерно такой:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
private void write(Connection conn) throws Exception {
	PreparedStatement masterStmt = null; 
	PreparedStatement firstChildStmt = null;
	PreparedStatement secondChildStmt = null;
	
	long batchRecordCount = 1000; // Для примера, на самом деле это настроечный параметр
	long commitRecordCount = batchRecordCount*10; // Для примера, на самом деле это настроечный параметр (должно делиться нацело на batchRecordCount)

    	long bCnt = 0; // счетчик кол-ва обработанных записей

    	try {   
		// готовим PreparedStatement-ы для всех необходимых INSERT-Ов
        	masterStmt = conn.prepareStatement(masterSQL);
        	firstChildStmt = conn.prepareStatement(firstChildSQL);
        	secondChildStmt = conn.prepareStatement(secondChildSQL);
		// остальные сущности для краткости пропущены

		// пакетная вставка
	    	for (СalcMasterObject master : masterMap.values()) {
			// установка bind-переменных
                	masterStmt.setLong(1, master.masterData.getId());
			// и так далее ...
	    		
	    		masterStmt.addBatch();
	    		bCnt++; // считаем кол-во строк
	    		
			// Аналогично сохраняем дочерние сущности
	    		for (firstChildData fcd : master.firstChilds.values()) {
	    			firstChildStmt.setLong(1, fcd.getId()); // и так далее ...
	    			....
	    			firstChildStmt.addBatch();
	    		}
	    		for (secondChildData scd : master.secondChilds.values()) {
	    			secondChildStmt.setLong(1, scd.getId()); // и так далее ...

	    			secondChildStmt.addBatch();
	    		}
			
			// остальные сущности для краткости пропущены
			....

			// сохранение порции с commit-ом
	    		if (bCnt%batchRecordCount == 0) {
		    	    	masterStmt.executeBatch(); 	masterStmt.clearBatch();
		    	    	firstChildStmt.executeBatch();	firstChildStmt.clearBatch();
		    	    	secondChildStmt.executeBatch();	secondChildStmt.clearBatch();

		    		if (bCnt%commitRecordCount == 0) {
		    			conn.commit();
		    		}
	    		}
		}
		// сохранение последней (неполной) порции с commit-ом
    		if (bCnt%batchRecordCount != 0) {
		    	masterStmt.executeBatch();
		    	firstChildStmt.executeBatch();
		    	secondChildStmt.executeBatch();

    			conn.commit();
    		}
    		
	} catch (Throwable e){
		// здесь необходимая обработка исключений, в том числе явный откат транзакции
		conn.rollback();
		...
		throw e;
	} finally {
		// освобождение ресурсов
	}
}
...
Рейтинг: 0 / 0
знатокам spring-а
    #38138075
am_sasa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
LVA,

а каким боком тут нужен spring?
...
Рейтинг: 0 / 0
знатокам spring-а
    #38138076
LVA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LVA
Гость
am_sasa,

уже написанный код находится на инспекции.
требование главного архитектора - перенести все на спринг
...
Рейтинг: 0 / 0
знатокам spring-а
    #38138133
am_sasa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
LVA,
ну тогда делай из
Код: java
1.
2.
3.
4.
5.
long batchRecordCount;
long commitRecordCount;
String masterSQL;
String firstChildSQL;
String secondChildSQL;

поля класса с сеттерами
а в спринге
Код: xml
1.
2.
3.
4.
5.
<bean class="...">
   <property name="batchRecordCount" value="1000">
   ...
     <property name="masterSQL" value="select * from table">
</bean>



зачем тут еще спринг нужен не знаю..
...
Рейтинг: 0 / 0
знатокам spring-а
    #38138162
LVA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LVA
Гость
am_sasa,
дело не в инжекте этих полей. Требование - уйти от работы на уровне jdbc :)
Если что то действительно нельзя сделать иначе, кроме как через jdbc, то надо аргументировать, почему нельзя.
Сейчас требование такое: работать через jdbcTemplate, который собственно и будет инжектиться. Доступ к данным вынести в DAO. Алгоритм должен дергать какой нибудь DAO, в котором будет пакетная вставка с помощью jdbcTemplate, ну или чего-то подобного).

но вот я не нахожу в jdbcTemplate возможности сделать по человечески то, что сделано сейчас на jdbc.
то ли задача нестандартная, то ли просто не там или не так ищу, потому что опыта нет в данной технологии.
...
Рейтинг: 0 / 0
знатокам spring-а
    #38138270
pavel_nv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По идее если обернуть 2-3 вызова JdbcTepmlate.BatchUpdate() в одном @Transactional методе, то они будут в одной транзакции.
...
Рейтинг: 0 / 0
знатокам spring-а
    #38138294
pavel_nv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и рулить уже имя с помощью Propagation.REQUIRED и Propagation.REQUIRES_NEW
...
Рейтинг: 0 / 0
знатокам spring-а
    #38138303
LVA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LVA
Гость
pavel_nv,

в БД будут вставляться сотни тысяч записей (в каждую из таблиц, в некоторые из таблиц деталей - миллионы), каждый отдельный JdbcTepmlate.BatchUpdate() - это новый prepareStatement, как я понимаю. это явно не хорошо.
Один из вопросов: как добиться многократного использования уже отпрепаренного стэйтмента.
...
Рейтинг: 0 / 0
знатокам spring-а
    #38138312
LVA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LVA
Гость
pavel_nvи рулить уже имя с помощью Propagation.REQUIRED и Propagation.REQUIRES_NEW

это уже другой вопрос.
если у меня @Transactional метод, делает чтение из БД, обработку и переходит к записи. я, допустим, запись в БД выношу в еще один @Transactional метод - это что будет: новое соединение (сессия) или новая транзакция в том же соединении ? нужно второе.
...
Рейтинг: 0 / 0
знатокам spring-а
    #38138329
pavel_nv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LVA,

то что на 1к записей БД будет парсить запрос 1 раз - в пределах погрешности, я б не заморачивался.
...
Рейтинг: 0 / 0
знатокам spring-а
    #38138376
LVA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LVA
Гость
pavel_nvто что на 1к записей БД будет парсить запрос 1 раз - в пределах погрешности, я б не заморачивался.

система (и БД) высоконагруженная. таблиц много. размер пачки настраивается. например, для оракла рекомендуется 100, максимум 500 записей в пачке, далее заметного прироста производительности не наблюдается. зато ресурсов тратится намного больше. правда, это рекомендация для pl/sql, где нет передачи данных по сети, может при работе через jdbc->DOA рекомендации и другие, не знаю.

честно говоря, такой рефакторинг приводит только к ухудшению характеристик. печально.
...
Рейтинг: 0 / 0
знатокам spring-а
    #38138594
chpasha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
для начала я бы проверил
а) поддерживается ли на уровне драйвера и бд кэширование стейтментов
б) на сколько просядет производительность на batchUpdate. если заметно - доложить шефу. если фигня - делать как велят.
c) почему нужно вставлять именно 1000 мастер, 1000 деталь1, 1000 деталь2? почему нельзя все мастер по 1000, все деталь1 по 1000 и т.д.?
...
Рейтинг: 0 / 0
знатокам spring-а
    #38138646
LVA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LVA
Гость
chpasha,

1. поддерживается
2. не уверен, что замер в тепличных условиях и замер в боевых (многопользовательская высоконагруженная система с большой конкуренцией за ресурсы) будут сопоставимы. да и объем данных такой мне на имеющейся локальной БД не потянуть. Попробовал бы все равно замерить, но под спринг код еще не написан, когда напишу - можно посмотреть. но пока вопрос - стоит ли так вообще писать. и можно ли написать как то по другому, но через спринг.
3. потому что нужно соблюсти целостность данных. 1000 строк мастера, и все его детали - это цельная информация, которая коммитится. А иметь закоммиченными 1 млн строк матстера без деталей - это кривые данные :))
...
Рейтинг: 0 / 0
знатокам spring-а
    #38138708
pavel_nv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
знатокам spring-а
    #38138859
chpasha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LVAchpasha,
1. поддерживается
тогда по логике ты ничего не выигрываешь.

LVAкогда напишу - можно посмотреть. но пока вопрос - стоит ли так вообще писать. и можно ли написать как то по другому, но через спринг.
можно, но это будет в стиле "шоб отстали". jdbcStatement.execute(ConnectionCallback) и ему подобные. но я бы накатал с batchUpdates и хоть приблизительно сравнил замеры. кстати на 100k записях возможно есть смысл подумать о средствах сервера, типа load from file или что там у вас.

LVA3. потому что нужно соблюсти целостность данных. 1000 строк мастера, и все его детали - это цельная информация
понятно.
...
Рейтинг: 0 / 0
знатокам spring-а
    #38139092
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LVA,
у тебя банальная заливка данных.
- спринг не для заливки данных
- я так понимаю, что заливка - это разовый процесс (ночной и т.д.)
Поэтому какая тут конкуренция и с кем?
ЗЫ. Не писать. Либо сделать замеры для "архитектора".
Возможно его не интересует производительность.
...
Рейтинг: 0 / 0
знатокам spring-а
    #38139102
chpasha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123- спринг не для заливки данных
имеется в виду спринговая обертка вокруг jdbc и спринговые декларативные транзакции.
...
Рейтинг: 0 / 0
знатокам spring-а
    #38139130
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chpasha,
ну, ты как всегда сужаешь, а я расширяю.
Я имел ввиду, что jdbc тут самое верное и гибкое решение (минимальное перед всякими СУБД-приблудами).
И не нужны тут никакие шаблоны, ОРМы и ДАО.
Но конкретно, что хочет его шеф, надо его звать.
Удачи аффтару.
______________________________________________
"Сложнее всего в мире достигнуть простоты — это крайняя граница опыта и последнее усилие гения". © George Sand.
AutoPOI.ru — ГИС-технологии для Oracle
...
Рейтинг: 0 / 0
знатокам spring-а
    #38139208
LVA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LVA
Гость
chpashaLVAchpasha,
1. поддерживается
тогда по логике ты ничего не выигрываешь.

не хотелось бы оффтопить. тема не об этом. просто скажу, что разница, безусловно, есть. так называемый "мягкий парсинг". Другое дело, оказывает ли эта разница заметное влияние. это вопрос сложный. Том Кайт говорит, что разница эта особенно заметна в высоконагруженных многопользовательских средах. В однопользовательском особой разницы, по видимому не будет. Исследовать этот вопрос в высоконагруженной среде для меня не представляется возможным. Но учитывать это надо, и если известно, что лучше парсить один раз, а не 1000, то надо делать именно так.
...
Рейтинг: 0 / 0
знатокам spring-а
    #38139217
LVA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LVA
Гость
Petro123LVA,
у тебя банальная заливка данных.
- спринг не для заливки данных
- я так понимаю, что заливка - это разовый процесс (ночной и т.д.)
Поэтому какая тут конкуренция и с кем?
ЗЫ. Не писать. Либо сделать замеры для "архитектора".
Возможно его не интересует производительность.

у меня не банальная заливка, а мощная расчетная процедура в системе 24х7, и работать она может в любой момент, параллельно с ней работают (и изменяют данные) еще много-много сессий.
Поскольку объем расчитанных данных очень велик, и время расчета тоже велико, то сохранять все в одной транзакции довольно смело. посему реализован механизм порционного сохранения, а алгоритм поддерживает инкрементальный досчет в случае ошибок.

Petro123Я имел ввиду, что jdbc тут самое верное и гибкое решение (минимальное перед всякими СУБД-приблудами).
И не нужны тут никакие шаблоны, ОРМы и ДАО.
Но конкретно, что хочет его шеф, надо его звать.

я тоже так думаю, что никакие фреймворки здесь не нужны. лучше, чем на JDBC, не сделать. И это для меня наиболее понятный и простой код, поскольку с БД дружу.
А с архитектором спорил до хрипоты. но он хочет, чтобы все и у всех было в одном стиле. А стиль этот он всем собирается прививать :))

JDBC - работать нельзя, мол придет кто то после меня - ничего в этом не поймет. вот так :)

Даже работать со Statement-ом или RecordSet-ом (полученным в том числе и из спринга) напрямую не дает. Возможный resource leak - вот такой странный для меня аргумент. Используйте callback-интерфейсы, ага.
хотя, если руки кривые, то всегда можно налажать, даже со спрингом, который сам управляет ресурсами, выдав мне в руки распрекрасный jdbcTemplate.

В итоге, кто то (я ) должен уступить, иначе дело встанет. Поэтому это тоже оффтоп :)
...
Рейтинг: 0 / 0
знатокам spring-а
    #38139218
LVA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
LVA
Гость
pavel_nv 10.5.7 Transaction propagation

да, читал, но не совсем понял. когда REQUIRED_NEW, то написано, что используется новая транзакция, но не ясно до конца, новая ли это сессия ? или это что то вроде автономной транзакции (хотя для этого вроде бы есть еще PROPAGATION_NESTED) ...
...
Рейтинг: 0 / 0
знатокам spring-а
    #38139323
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LVA,
Все верно пишите. Выхода у вас нет. Если 24 на 7 то вы обязаны сделать тесты под нагрузкой. Причем конкурентной.
А транзакции в реале посмотрите из СУБД.
Ну и отпишитесь.
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / знатокам spring-а
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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