Можно ли запустить несколько операторов DDL внутри транзакции (внутри SQL Server)?

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

Если статические атрибуты получают экземпляр до того, как класс получает экземпляр через его конструктор, статические атрибуты внутри вложенных статических классов похоже, не создаются экземпляром до тех пор, пока не будет вызван конструктор класса или, по крайней мере, до тех пор, пока не будут указаны первые атрибуты, даже если они отмечены как «final».

Рассмотрим этот пример:

public class C0 {

    static C0 instance = null;

    // Uncomment the following line and a null pointer exception will be
    // generated before anything gets printed.
    //public static final String outerItem = instance.makeString(98.6);

    public C0() {
        instance = this;
    }

    public String makeString(int i) {
        return ((new Integer(i)).toString());
    }

    public String makeString(double d) {
        return ((new Double(d)).toString());
    }

    public static final class nested {
        public static final String innerItem = instance.makeString(42);
    }

    static public void main(String[] argv) {
        System.out.println("start");
        // Comment out this line and a null pointer exception will be
        // generated after "start" prints and before the following
        // try/catch block even gets entered.
        new C0();
        try {
            System.out.println("retrieve item: " + nested.innerItem);
        }
        catch (Exception e) {
            System.out.println("failed to retrieve item: " + e.toString());
        }
        System.out.println("finish");
    }
}

Хотя «вложенные» и «innerItem» объявляются как «статические окончательные». параметр nested.innerItem не выполняется до тех пор, пока не будет создан экземпляр класса (или, по крайней мере, до тех пор, пока не будет указан первый вложенный статический элемент), как вы можете убедиться сами, комментируя и раскомментируя строки, на которые я ссылаюсь, выше. То же самое не относится к «externalItem».

По крайней мере, это то, что я вижу в Java 6.0.

29
задан Michał Politowski 2 August 2017 в 08:37
поделиться

4 ответа

Я знаю, что у большинства баз данных есть ограничения, но у Postgres нет. Вы можете запускать любые создания числовых таблиц, изменения столбцов и индексов в транзакции, и эти изменения не будут видны другим пользователям, пока не завершится COMMIT. Вот какими должны быть базы данных! : -)

Что касается SQL Server, вы можете запускать DDL внутри транзакции, но SQL Server не поддерживает метаданные версии , и поэтому изменения будут видны другим перед фиксацией транзакции. Но некоторые операторы DDL можно откатить, если вы находитесь в транзакции , но для каких из них работает, а для каких нет, вам нужно будет выполнить некоторые тесты.

13
ответ дан David Roussel 2 August 2017 в 08:37
поделиться

Если вы создаете таблицы, представления и т. Д. На лету (кроме табличных переменных или временных таблиц), вам, возможно, придется по-настоящему переосмыслить свой дизайн. Это не то, что обычно должно происходить из пользовательского интерфейса. Даже если вы должны разрешить некоторую настройку, операторы DDL не должны выполняться одновременно с выполнением транзакционных вставок / обновлений / удалений. Гораздо лучше разделить эти функции.

Это также то, что требует разумной дозы рассмотрения и проверки того, что происходит, когда два пользователя одновременно пытаются изменить структуру одной и той же таблицы и затем выполнить транзакцию для вставки данных. Есть некоторые действительно страшные вещи, которые могут случиться, когда вы позволяете пользователям вносить изменения в структуру вашей базы данных.

Кроме того, некоторые операторы DDL всегда должны быть первым оператором пакета. Обращайте на это внимание и во время их запуска.

4
ответ дан HLGEM 2 August 2017 в 08:37
поделиться

Может ли быть так, что в MS SQL неявные транзакции запускаются при выполнении операторов DDL и DML. Если вы отключите эту опцию, это поможет, используйте SET IMPLICIT_TRANSACTIONS

РЕДАКТИРОВАТЬ: другая возможность - вы не можете комбинировать CREATE VIEW с другими операторами в том же пакете. CREATE TABLE в порядке. Вы разделяете партии с помощью GO.

EDIT2: вы МОЖЕТЕ использовать несколько DDL в транзакции, если они разделены GO для создания разных пакетов.

1
ответ дан Tom H 2 August 2017 в 08:37
поделиться

Для общего случая и IIRC небезопасно предполагать, что операторы DDL являются транзакционными.

. Другими словами, существует большая свобода действий в отношении того, как изменения схемы взаимодействуют в транзакции (при условии, что это вообще происходит). Я считаю, что это может быть поставщик или даже конкретная установка (то есть до dba). Так что, по крайней мере, не используйте одну СУБД, чтобы предположить, что другие будут рассматривать операторы DDL как слово.

Изменить: MySql - это пример СУБД, которая вообще не поддерживает транзакции DDL. Кроме того, если у вас есть репликация / зеркалирование базы данных, вы должны быть очень осторожны, чтобы служба репликации (репликация Sybase является нормой, хотите верьте, хотите нет) на самом деле реплицирует оператор DDL.

1
ответ дан 28 November 2019 в 02:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: