Дорабатываю добавление блоков.
Улучшил класс записыватель в БД.
This commit is contained in:
AidarKC 2025-12-24 17:01:10 +03:00
parent a309b6f3ef
commit 4759521176
2 changed files with 13 additions and 30 deletions

View File

@ -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);

View File

@ -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) {