Любые идеи для сохранения транзакции в режиме базы данных H2 в памяти?

Следующий код для базы данных H2 с режимом в памяти работает отлично, пока соединение не открыто или не запущена виртуальная машина. Но H2 db теряет данные, когда соединение закрывается или когда происходит отключение виртуальной машины. Есть ли какой-либо другой способ сохранить данные в течение нескольких циклов запуска-выключения/включения-офлайн?

Одним из способов может быть создание дисковой реплики базы данных в памяти путем отслеживания DDL и DML, выпущенных приложением, и процесса синхронизации в фоновом режиме, который проверяет целостность данных на диске и в памяти. Дисковые DML могут быть медленнее + дополнительные накладные расходы на копирование/загрузку данных с диска в память при каждом запуске будут присутствовать, но все же сохранение в некоторой степени будет достижимо.

Существуют ли какие-либо другие способы, предоставляемые H2 для решения проблемы с сохранением в режиме в памяти или какие-либо другие обходные пути?

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class H2InMemoryModeTest {        

public static void main(String[] args)
    {
        try
        {
            Class.forName("org.h2.Driver");
            
           DriverManager.getConnection("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1","sa","sa");
            
            Statement stmt = con.createStatement();
            
            //stmt.executeUpdate( "DROP TABLE table1" );
            stmt.executeUpdate( "CREATE TABLE table1 ( user varchar(50) )" );
            stmt.executeUpdate( "INSERT INTO table1 ( user ) VALUES ( 'John' )" );
            stmt.executeUpdate( "INSERT INTO table1 ( user ) VALUES ( 'Smith' )" );
            ResultSet rs = stmt.executeQuery("SELECT * FROM table1");
            
            while( rs.next() )
            {
                String name = rs.getString("user");
                System.out.println( name );
            }
            stmt.close();
            con.close();
        }
        catch( Exception e )
        {
            System.out.println( e.getMessage() );
        }
    }
}

Пожалуйста, помогите. Спасибо.


person Dhwanit    schedule 10.08.2013    source источник
comment
Не могли бы вы использовать постоянный режим с большой кеш? Что касается сохранения базы данных в памяти, рассматривали ли вы команду SCRIPT TO?   -  person Thomas Mueller    schedule 10.08.2013
comment
Большой кеш — хороший вариант, но не для агрегированных запросов или тех, которые требуют полного сканирования таблицы при отсутствии индексов. Также хорошей стратегией окажется добавление индексов с явным кэшированием. SCRIPT TO выглядит многообещающе, но его необходимо запускать, как синхронизацию контрольных точек, чтобы делать периодический снимок базы данных, чтобы максимизировать восстановление до последнего состояния базы данных в случае сбоя системы / отключения питания / нехватки памяти. Что скажешь, Томас Мюллер?   -  person Dhwanit    schedule 11.08.2013


Ответы (2)


Вы можете использовать постоянный режим с большой кеш. Под «большим» я подразумеваю, чтобы вся база данных помещалась в памяти. Таким образом, даже сканирование таблиц не будет читать с диска.

Чтобы сохранить базу данных в памяти, вы можете использовать команду SCRIPT, но вам нужно выполнить его вручную.

person Thomas Mueller    schedule 11.08.2013
comment
Кстати, даже при задании большого размера кеша движку sql потребуется хотя бы один раз переместить только ту часть данных с диска в кеш, которая требуется для обслуживания этого запроса, а позже эти данные могут оставаться в кеше. А вот как работает внутреннее кэширование - это еще вопрос. Можете ли вы явно указать H2 в постоянном режиме, чтобы сохранить некоторую таблицу «X» в кеше? И для SCRIPT TO это выглядит многообещающе для режима памяти в некоторой степени, но его необходимо запускать, как событие контрольной точки, чтобы делать периодические снимки базы данных, чтобы максимизировать восстановление до последнего состояния базы данных ближайшего времени в случае любого сбоя. - person Dhwanit; 11.08.2013
comment
хотя бы один раз переместите только эту часть данных с диска в кеш: конечно, а как еще вы хотите загрузить данные с диска в память? Если вы не хотите загружать его в память, вам вообще не нужно сохранять изменение. как работает внутреннее кэширование - это еще вопрос: в чем ваш вопрос и зачем вам это знать? - person Thomas Mueller; 12.08.2013

Это не так уж сложно, просто следуйте моему изменению кода ниже

Пожалуйста, измените spring.datasource.url=jdbc:h2:~/test;MVCC=true;DB_CLOSE_DELAY=-1;MODE=Oracle, это создаст тестовый файл данных в локальной системе C:\Users\yourname .. здесь test. mv файл создаст

Я надеюсь, что это может помочь вам

person Community    schedule 24.08.2017