提交 4f4ab94c authored 作者: Thomas Mueller's avatar Thomas Mueller

Issue 28: Multi version concurrency (MVCC): when a row was updated or deleted,…

Issue 28: Multi version concurrency (MVCC): when a row was updated or deleted, but this change was rolled back, the row was not visible by other sessions if no index was used to access it.
上级 8e319b3b
......@@ -16,7 +16,9 @@ Change Log
<h1>Change Log</h1>
<h2>Next Version (unreleased)</h2>
<ul><li>Views with multiple joined tables (where one was an outer join) couldn't be used in some cases. Fixed.
<ul><li>Multi version concurrency (MVCC): when a row was updated or deleted, but this change was rolled back,
the row was not visible by other sessions if no index was used to access it. Fixed.
</li><li>Views with multiple joined tables (where one was an outer join) couldn't be used in some cases. Fixed.
</li><li>Fixed the Oracle mode: Oracle allows multiple rows with NULL in a unique index.
</li><li>Running out of memory could result in incomplete transactions or corrupted databases. Fixed.
</li><li>When using order by in a query that uses the same table multiple times, the order could
......
......@@ -116,6 +116,8 @@ public class UndoLogRecord {
try {
row.setPos(0);
table.addRow(session, row);
// reset session id, otherwise other session think this row was inserted by this session
row.commit();
} catch (SQLException e) {
if (session.getDatabase().getLockMode() == Constants.LOCK_MODE_OFF
&& e.getErrorCode() == ErrorCode.DUPLICATE_KEY_1) {
......
......@@ -270,6 +270,12 @@ java org.h2.test.TestAll timer
/*
drop all objects;
create domain email as varchar;
create table test(e email);
select * from INFORMATION_SCHEMA.COLUMNS where table_name='TEST';
script nosettings;
add download link
Check Eclipse DTP, see also
......
......@@ -19,6 +19,59 @@ public class TestMvcc3 extends TestBase {
public void test() throws Exception {
testSequence();
testDisableAutoCommit();
testRollback();
}
private void testRollback() throws Exception {
if (!config.mvcc) {
return;
}
deleteDb("mvcc3");
Connection conn = getConnection("mvcc3");
Statement stat = conn.createStatement();
stat.executeUpdate("DROP TABLE IF EXISTS TEST");
stat.executeUpdate("CREATE TABLE TEST (ID NUMBER(2) PRIMARY KEY, VAL VARCHAR(10))");
stat.executeUpdate("INSERT INTO TEST (ID, VAL) VALUES (1, 'Value')");
stat.executeUpdate("INSERT INTO TEST (ID, VAL) VALUES (2, 'Value')");
if (!config.memory) {
conn.close();
conn = getConnection("mvcc3");
}
conn.setAutoCommit(false);
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
Connection conn2 = getConnection("mvcc3");
conn2.setAutoCommit(false);
conn2.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
conn.createStatement().executeUpdate("UPDATE TEST SET VAL='Updated' WHERE ID = 1");
conn.rollback();
ResultSet rs = conn2.createStatement().executeQuery("SELECT * FROM TEST");
assertTrue(rs.next());
assertEquals("Value", rs.getString(2));
assertTrue(rs.next());
assertEquals("Value", rs.getString(2));
assertFalse(rs.next());
conn.createStatement().executeUpdate("UPDATE TEST SET VAL='Updated' WHERE ID = 1");
conn.commit();
rs = conn2.createStatement().executeQuery("SELECT * FROM TEST ORDER BY ID");
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
assertEquals("Updated", rs.getString(2));
assertTrue(rs.next());
assertEquals(2, rs.getInt(1));
assertEquals("Value", rs.getString(2));
assertFalse(rs.next());
conn.close();
conn2.close();
}
private void testDisableAutoCommit() throws Exception {
if (!config.mvcc) {
return;
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论