提交 c2b4d9db authored 作者: Noel Grandin's avatar Noel Grandin

fix concurrent access to views array in Table

as a consequence of my previous change to create views on the current session instead of the system session
上级 efee13cf
...@@ -8,6 +8,7 @@ package org.h2.command.ddl; ...@@ -8,6 +8,7 @@ package org.h2.command.ddl;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.CommandInterface; import org.h2.command.CommandInterface;
import org.h2.command.Parser; import org.h2.command.Parser;
...@@ -274,9 +275,8 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -274,9 +275,8 @@ public class AlterTableAlterColumn extends SchemaCommand {
throw DbException.get(ErrorCode.VIEW_IS_INVALID_2, e, getSQL(), e.getMessage()); throw DbException.get(ErrorCode.VIEW_IS_INVALID_2, e, getSQL(), e.getMessage());
} }
String tableName = table.getName(); String tableName = table.getName();
ArrayList<TableView> views = table.getViews(); CopyOnWriteArrayList<TableView> views = table.getViews();
if (views != null) { if (views != null) {
views = New.arrayList(views);
for (TableView view : views) { for (TableView view : views) {
table.removeView(view); table.removeView(view);
} }
......
...@@ -5,8 +5,7 @@ ...@@ -5,8 +5,7 @@
*/ */
package org.h2.command.ddl; package org.h2.command.ddl;
import java.util.ArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.CommandInterface; import org.h2.command.CommandInterface;
import org.h2.constraint.ConstraintReferential; import org.h2.constraint.ConstraintReferential;
...@@ -74,7 +73,7 @@ public class DropTable extends SchemaCommand { ...@@ -74,7 +73,7 @@ public class DropTable extends SchemaCommand {
throw DbException.get(ErrorCode.CANNOT_DROP_TABLE_1, tableName); throw DbException.get(ErrorCode.CANNOT_DROP_TABLE_1, tableName);
} }
if (dropAction == ConstraintReferential.RESTRICT) { if (dropAction == ConstraintReferential.RESTRICT) {
ArrayList<TableView> views = table.getViews(); CopyOnWriteArrayList<TableView> views = table.getViews();
if (views != null && views.size() > 0) { if (views != null && views.size() > 0) {
StatementBuilder buff = new StatementBuilder(); StatementBuilder buff = new StatementBuilder();
for (TableView v : views) { for (TableView v : views) {
......
...@@ -10,6 +10,8 @@ import java.util.Arrays; ...@@ -10,6 +10,8 @@ import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicReference;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.Prepared; import org.h2.command.Prepared;
import org.h2.constraint.Constraint; import org.h2.constraint.Constraint;
...@@ -77,7 +79,7 @@ public abstract class Table extends SchemaObjectBase { ...@@ -77,7 +79,7 @@ public abstract class Table extends SchemaObjectBase {
private ArrayList<TriggerObject> triggers; private ArrayList<TriggerObject> triggers;
private ArrayList<Constraint> constraints; private ArrayList<Constraint> constraints;
private ArrayList<Sequence> sequences; private ArrayList<Sequence> sequences;
private ArrayList<TableView> views; private AtomicReference<CopyOnWriteArrayList<TableView>> views;
private ArrayList<TableSynonym> synonyms; private ArrayList<TableSynonym> synonyms;
private boolean checkForeignKeyConstraints = true; private boolean checkForeignKeyConstraints = true;
private boolean onCommitDrop, onCommitTruncate; private boolean onCommitDrop, onCommitTruncate;
...@@ -398,8 +400,8 @@ public abstract class Table extends SchemaObjectBase { ...@@ -398,8 +400,8 @@ public abstract class Table extends SchemaObjectBase {
if (sequences != null) { if (sequences != null) {
children.addAll(sequences); children.addAll(sequences);
} }
if (views != null) { if (views.get() != null) {
children.addAll(views); children.addAll(views.get());
} }
if (synonyms != null) { if (synonyms != null) {
children.addAll(synonyms); children.addAll(synonyms);
...@@ -519,15 +521,15 @@ public abstract class Table extends SchemaObjectBase { ...@@ -519,15 +521,15 @@ public abstract class Table extends SchemaObjectBase {
} }
} }
public ArrayList<TableView> getViews() { public CopyOnWriteArrayList<TableView> getViews() {
return views; return views.get();
} }
@Override @Override
public void removeChildrenAndResources(Session session) { public void removeChildrenAndResources(Session session) {
while (views != null && views.size() > 0) { while (views.get() != null && views.get().size() > 0) {
TableView view = views.get(0); TableView view = views.get().get(0);
views.remove(0); views.get().remove(0);
database.removeSchemaObject(session, view); database.removeSchemaObject(session, view);
} }
while (synonyms != null && synonyms.size() > 0) { while (synonyms != null && synonyms.size() > 0) {
...@@ -811,10 +813,13 @@ public abstract class Table extends SchemaObjectBase { ...@@ -811,10 +813,13 @@ public abstract class Table extends SchemaObjectBase {
private static void remove(ArrayList<? extends DbObject> list, DbObject obj) { private static void remove(ArrayList<? extends DbObject> list, DbObject obj) {
if (list != null) { if (list != null) {
int i = list.indexOf(obj); list.remove(obj);
if (i >= 0) { }
list.remove(i); }
}
private static <T> void remove(AtomicReference<CopyOnWriteArrayList<T>> list, T obj) {
if (list.get() != null) {
list.get().remove(obj);
} }
} }
...@@ -886,7 +891,7 @@ public abstract class Table extends SchemaObjectBase { ...@@ -886,7 +891,7 @@ public abstract class Table extends SchemaObjectBase {
* @param view the view to add * @param view the view to add
*/ */
public void addView(TableView view) { public void addView(TableView view) {
views = add(views, view); add(views, view);
} }
/** /**
...@@ -940,6 +945,14 @@ public abstract class Table extends SchemaObjectBase { ...@@ -940,6 +945,14 @@ public abstract class Table extends SchemaObjectBase {
return list; return list;
} }
private static <T> void add(AtomicReference<CopyOnWriteArrayList<T>> list, T obj) {
if (list.get() == null) {
list.compareAndSet(null, new CopyOnWriteArrayList<T>());
}
// self constraints are two entries in the list
list.get().add(obj);
}
/** /**
* Fire the triggers for this table. * Fire the triggers for this table.
* *
......
...@@ -9,6 +9,7 @@ import java.util.ArrayList; ...@@ -9,6 +9,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.Prepared; import org.h2.command.Prepared;
import org.h2.command.dml.Query; import org.h2.command.dml.Query;
...@@ -135,10 +136,7 @@ public class TableView extends Table { ...@@ -135,10 +136,7 @@ public class TableView extends Table {
return e; return e;
} }
} }
ArrayList<TableView> views = getViews(); CopyOnWriteArrayList<TableView> views = getViews();
if (views != null) {
views = New.arrayList(views);
}
initColumnsAndTables(session, false); initColumnsAndTables(session, false);
if (views != null) { if (views != null) {
for (TableView v : views) { for (TableView v : views) {
...@@ -163,7 +161,7 @@ public class TableView extends Table { ...@@ -163,7 +161,7 @@ public class TableView extends Table {
tables = New.arrayList(query.getTables()); tables = New.arrayList(query.getTables());
ArrayList<Expression> expressions = query.getExpressions(); ArrayList<Expression> expressions = query.getExpressions();
ArrayList<Column> list = New.arrayList(); ArrayList<Column> list = New.arrayList();
ColumnNamer columnNamer= new ColumnNamer(session); ColumnNamer columnNamer= new ColumnNamer(session);
for (int i = 0, count = query.getColumnCount(); i < count; i++) { for (int i = 0, count = query.getColumnCount(); i < count; i++) {
Expression expr = expressions.get(i); Expression expr = expressions.get(i);
String name = null; String name = null;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论