diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/BlockchainDbWriter.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/BlockchainWriter.java similarity index 63% rename from shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/BlockchainDbWriter.java rename to shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/BlockchainWriter.java index 60b9f62..905f04f 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/BlockchainDbWriter.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/BlockchainWriter.java @@ -15,25 +15,19 @@ import java.sql.SQLException; * Важно: * - Здесь обеспечивается атомарность записи: либо вставился блок и обновилось состояние, либо не вставилось ничего. * - Соединение открывается/закрывается внутри (удобно для хэндлера). - * - При необходимости можно вызвать appendBlockAndState(Connection, ...) и управлять транзакцией снаружи. */ -public final class BlockchainDbWriter { +public final class BlockchainWriter { private final SqliteDbController db; private final BlocksDAO blocksDAO; private final BlockchainStateDAO stateDAO; - public BlockchainDbWriter(BlocksDAO blocksDAO, BlockchainStateDAO stateDAO) { + public BlockchainWriter(BlocksDAO blocksDAO, BlockchainStateDAO stateDAO) { this.db = SqliteDbController.getInstance(); this.blocksDAO = blocksDAO; this.stateDAO = stateDAO; } - /** - * Публичный метод: сам открывает соединение, делает транзакцию и закрывает соединение. - * - * @return true если всё записалось успешно, иначе кидает SQLException (или IllegalStateException выше по коду). - */ public void appendBlockAndState( String login, String blockchainName, @@ -44,56 +38,45 @@ public final class BlockchainDbWriter { String newHashHex ) throws SQLException { - // 1) Открываем соединение (try-with-resources гарантирует закрытие) try (Connection c = db.getConnection()) { - // 2) Включаем ручное управление транзакцией boolean oldAutoCommit = c.getAutoCommit(); c.setAutoCommit(false); try { - // 3) Внутри одной транзакции: - // - вставляем строку блока - // - обновляем/создаём blockchain_state - appendBlockAndState(c, login, blockchainName, globalNumber, prevGlobalHashHex, blockBytes, stOrNull, newHashHex); + // 1) блок + insertBlockRow(c, login, blockchainName, globalNumber, prevGlobalHashHex, blockBytes); - // 4) Фиксируем транзакцию + // 2) state + appendState(c, blockchainName, globalNumber, stOrNull, newHashHex); + + // 3) commit c.commit(); } catch (Exception e) { - // 5) Если что-то упало — откатываем транзакцию, чтобы не было "полузаписей" try { c.rollback(); } catch (SQLException ignore) {} - // Пробрасываем как SQLException (чтобы вызывающий код мог отдать internal_error и т.п.) if (e instanceof SQLException se) throw se; throw new SQLException("appendBlockAndState failed", e); } finally { - // 6) Возвращаем autoCommit как было try { c.setAutoCommit(oldAutoCommit); } catch (SQLException ignore) {} } } } /** - * Внутренний/расширенный метод: запись в рамках УЖЕ открытого соединения. - * Удобно если снаружи хотят объединить несколько действий в одну транзакцию. + * Обновление состояния blockchain_state (создаём если отсутствует). + * Пока линии не используются: lineIndex=0 и lineHash = globalHash. */ - public void appendBlockAndState( + private void appendState( Connection c, - String login, String blockchainName, int globalNumber, - String prevGlobalHashHex, - byte[] blockBytes, BlockchainStateEntry stOrNull, String newHashHex ) throws SQLException { - // A) Вставляем блок (строка в таблицу blocks) - insertBlockRow(c, login, blockchainName, globalNumber, prevGlobalHashHex, blockBytes); - - // B) Обновляем состояние blockchain_state (создаём если отсутствует) BlockchainStateEntry st = stOrNull; if (st == null) { st = new BlockchainStateEntry(); @@ -104,7 +87,7 @@ public final class BlockchainDbWriter { st.setLastGlobalNumber(globalNumber); st.setLastGlobalHash(newHashHex); - // Пока линии не используются: lineIndex=0 и lineHash = globalHash + // Линии пока не используются: lineIndex=0 и lineHash=globalHash st.setLastLineNumber(0, globalNumber); st.setLastLineHash(0, newHashHex); diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/Net_AddBlock_Handler.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/Net_AddBlock_Handler.java index 303310f..f54fb8b 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/Net_AddBlock_Handler.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/Net_AddBlock_Handler.java @@ -40,7 +40,7 @@ public final class Net_AddBlock_Handler implements JsonMessageHandler { private final SolanaUsersDAO solanaUsersDAO = SolanaUsersDAO.getInstance(); // Writer отвечает за транзакции/атомарность и консистентность БД - private final BlockchainDbWriter dbWriter = new BlockchainDbWriter(blocksDAO, stateDAO); + private final BlockchainWriter dbWriter = new BlockchainWriter(blocksDAO, stateDAO); @Override public Net_Response handle(Net_Request baseReq, ConnectionContext ctx) {