//Wenn Die Transaction erst nach sess2.close() gestartet wird, dann funktioniert es
Transaction t = sess1.beginTransaction();
Session sess2 = DBConnection.openSession();
//Wenn um den query eine Transaction gelegt wird, funktioniert es auch
// Transaction t2 = sess2.beginTransaction();
System.out.println("Number of animals " + sess2.createCriteria(Animal.class).list().size());
// t2.commit();
sess2.close();
Animal a = new Animal();
sess1.save(a);
sess1.flush();
t.commit();
sess1.close();
download/trace*.log
DatDb test
Short answer:
This database does not guarantee that all committed transactions survive a power failure.
While other databases (such as Derby) claim they can guarantee it, in reality they can't.
Testing shows that all databases lose transactions on power failure sometimes.
Where this is not acceptable, a laptop or UPS (uninterruptible power supply) should be used.
If durability is required for all possible cases of hardware failure, clustering should be used,
such as the H2 clustering mode.
Long answer:
Making sure that committed transaction are not lost is more complicated than it seems first.
To guarantee complete durability, a database must ensure that the log record is on the hard drive
before the commit call returns. To do that, different approaches are possible. The first option
is to use the 'synchronous write' option when opening a file. In Java, RandomAccessFile
supports the opening modes "rws" and "rwd":
Around 1000 write operations per second are possible when using one of those modes.
You can get the exact number for your system by running the test org.h2.test.poweroff.TestWrite.
This feature is used by Derby and PostgreSQL.
However, this alone does not force changes to disk, because it does not flush the operating system and hard drive buffers.
Even 7800 RPM hard drives can spin at 130 rounds per second only.
There are other ways force data to disk:
FileDescriptor.sync().
The documentation says that this will force all system buffers to synchronize with the underlying device.
Sync is supposed to return after all in-memory modified copies of buffers associated with this FileDescriptor have been written to the physical medium.
FileChannel.force() (since JDK 1.4).
This method is supposed to force any updates to this channel's file to be written to the storage device that contains it.
The test was made with this database, as well as with PostgreSQL, Derby, and HSQLDB.
None of those databases was able to guarantee complete transaction durability.
To test the durability / non-durability of this and other databases, you can use the test application in the package
org.h2.test.poweroff. Two computers with network connection are required to run this test.
One computer acts as the listener, the test application is run on the other computer.
The computer with the listener application opens a TCP/IP port and listens for an incoming connection.
The second computer first connects to the listener, and then created the databases and starts inserting records.
The connection is set to 'autocommit', which means after each inserted record a commit is performed automatically.
Afterwards, the test computer notifies the listener that this record was inserted successfully.
The listener computer displays the last inserted record number every 10 seconds.
Now, the power needs to be switched off manually while the test is still running.
Now you can restart the computer, and run the application again.
You will find out that in most cases, none of the databases contains all the records that the listener computer knows about.
For details, please consult the source code of the listener and test application.
The test was made using two computers, with computer A
writing to disk and then sending the transaction id over the network to computer B. After some time,
the power is switched off on computer A. After switching on computer A again, some committed
transactions where lost.
It is not enough to just send the write request to
the operating system, because the write cache may be enabled (which is the default for Windows XP).
Unfortunetly, it is also not enough to flush the buffers (fsync), because regular hard drives do not obey
this command. The only way to guarantee durability, according to a test, is to wait about one second
before returning from a commit call. This would mean the maximum number of transactions is 1 per second.
All databases tested achive a much higher transaction rate, which means all databases take some shortcuts.
H2 does not guarantee durability, and while other databases (such as Derby) claim they guarantee it,
in reality none of the tested databases achieve complete durability
There are multiple ways to
With regular hard drives, trying to
Durability means that
Mail P2P
DROP TABLE TEST;
DROP VIEW TEST_VIEW;
CREATE TABLE TEST(ID INT PRIMARY KEY);
@LOOP 1000 INSERT INTO TEST VALUES(?);
CREATE VIEW TEST_VIEW AS SELECT * FROM TEST;
EXPLAIN SELECT * FROM TEST_VIEW WHERE ID=10;
@LOOP 1000 SELECT * FROM TEST_VIEW WHERE ID=?;
@LOOP 1000 SELECT * FROM TEST WHERE ID=?;
DROP TABLE TEST;
DROP VIEW TEST_VIEW;
CREATE TABLE TEST(
PERSON_ID INT PRIMARY KEY,
NAME VARCHAR,
LOWER_NAME VARCHAR AS LOWER(NAME)
);
CREATE INDEX IDX_NAME ON TEST(LOWER_NAME);
EXPLAIN SELECT * FROM TEST WHERE LOWER_NAME LIKE '%';
EXPLAIN SELECT * FROM TEST WHERE LOWER_NAME LIKE '%' ORDER BY LOWER_NAME;
CREATE VIEW TEST_VIEW AS SELECT * FROM TEST;
EXPLAIN SELECT * FROM TEST_VIEW WHERE LOWER_NAME LIKE '%';
EXPLAIN SELECT * FROM TEST_VIEW WHERE LOWER_NAME LIKE '%' ORDER BY LOWER_NAME;
DROP TABLE TEST;
DROP VIEW TEST_VIEW;
CREATE TABLE TEST(ID INT PRIMARY KEY);
@LOOP 1000 INSERT INTO TEST VALUES(?);
CREATE VIEW TEST_VIEW AS SELECT * FROM TEST;
EXPLAIN SELECT * FROM TEST_VIEW WHERE ID=10;
@LOOP 1000 SELECT * FROM TEST_VIEW WHERE ID=?;
@LOOP 1000 SELECT * FROM TEST WHERE ID=?;
Currently there is no such feature, however it is quite simple to add a user defined function
READ_TEXT(fileName String) returning a CLOB. The performance would probably not be optimal,
but it should work. I am not sure if this will read the CLOB in memory however.
I will add this to the todo list.
Docs: Fix Quickstart
Dave Brewster (dbrewster at guidewire dot com): currency: Add a setting to allow BigDecimal extensions
Send SQL Injection solution proposal to PostgreSQL, MySQL, Derby, HSQLDB,...
Improve ACID documentation (durability problem)
Improve LOB in directories performance
Improve documentation for MAX_LENGTH_INPLACE_LOB
Convert SQL-injection-2.txt to html document, include SQLInjection.java sample
Integrate patches from Pavel Ganelin: www.dullesopen.com/software/h2-database-03-04-07-mod.src.zip
Test Eclipse DTP 1.5 (HSQLDB / H2 connection bug fixed)
Automate power off tests
Automate real power off tests
how to make -baseDir work for H2 Console?
Maybe add a little bit AdSense
Custom Captcha for the forum, to protect against spam bots (required for Google Code?)
CREATE [ TEMPORARY | TEMP ] SEQUENCE name [ INCREMENT [ BY ] increment ]
[ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
[ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]
http://db.apache.org/ddlutils/ (write a H2 driver)
*/
/*
...
...
@@ -138,6 +319,39 @@ insert into abc select * from dual where 1=0;
create local temporary table abc(id varchar) on commit drop;
insert into abc select * from dual;
drop table abc;
DROP TABLE TEST;
CREATE TABLE TEST(ID INT);
INSERT INTO TEST VALUES(1);
INSERT INTO TEST VALUES(2);
SELECT ID AS A FROM TEST WHERE A>0;
-- Yes: HSQLDB
-- Fail: Oracle, MS SQL Server, PostgreSQL, MySQL, H2, Derby