Должен ли я использовать транзакции SQL при чтении записей?

транзакции SQL используются для вставки, обновления, но должны ли они использоваться для чтения записей?

7 ответов


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

единственный раз, когда вам действительно нужна транзакция (и, часто, конкретный намек на блокировку) в процессе только для чтения являются:
- Вы читаете записи "piece-meal" и больше ничего не нужно, чтобы изменить значения, пока вы itterate хотя. [Например, подключенный набор записей в ADO, который затем просматривается курсором.]
- Вы читаете какие-то данные, делаете какие-то вычисления, затем читаете какие-то связанные данные, но, исходя из предположения, ничего не изменилось за это время.


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


перенос транзакций не требуется для чистого чтения.

в вашем операторе SQL подсказки блокировки должны заботиться о возвращении вам правильных данных (http://msdn.microsoft.com/en-us/library/aa213026%28SQL.80%29.aspx).

на уровне сервера можно задать уровни изоляции транзакций (http://msdn.microsoft.com/en-us/library/ms173763.aspx).

редактировать

объяснение чистого чтения

Если все ваши инструкции SQL имеют эти виды чтения, тогда вам не нужно обертывать транзакцию

SELECT Col1, Col2
From Table1
    INNER JOIN Table2
        ON Table1.Id = Table2.Table1Id

Если Вы читаете результаты, которые могут быть затронуты другими транзакциями параллельно, вы должны обернуть транзакцию. Например:

BEGIN TRANSACTION

INSERT INTO AccountTransactions (Type, Amount) Values ('Credit', 43.21)
UPDATE AccountSummary SET Balance = Balance + 43.21

SELECT @Balance = Balance FROM AccountSummary

COMMIT TRANSACTION

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


Если вам нужна самая последняя информация миллисекунды, вы можете использовать транзакцию, которая построена с помощью TransactionOptions имеющего IsolationLevel of Serializable.

это повлияет на производительность, поскольку он заблокирует таблицу (или части таблицы), поэтому вам нужно выяснить, действительно ли вам это нужно.

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

это действительно зависит от вашего приложения, какие данные он требует и как он использует его.

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


нет, транзакции обычно не нужны для чтения данных, и это замедлит чтение ваших данных.

Я бы предложил вам прочитать термин "атомный". Это поможет вам понять, для чего нужны транзакции.


можно совершать транзакции, но какова цель этого?

можно задать соответствующий уровень изоляции для всего сеанса SQL Server с помощью инструкции SET TRANSACTION ISOLATION LEVEL.

это синтаксис из SQL Server Books Online:

SET TRANSACTION ISOLATION LEVEL 
    {
        READ COMMITTED 
        | READ UNCOMMITTED 
        | REPEATABLE READ 
        | SERIALIZABLE
    }

блокировка в Microsoft SQL Server.


когда вы что-то изменили в транзакции, вы можете использовать инструкцию read, чтобы проверить, вступает ли операция в силу, непосредственно перед фиксацией.


транзакции предназначены для избежания проблем параллелизма, когда одна логическая транзакция фактически сопоставляется с несколькими SQL-запросами. Например, для банковского счета, если вы переводите деньги с одного счета на другой, вы сначала вычитаете сумму со счета, а затем добавите ее в другой(или наоборот). Но, если какая-то ошибка возникает между вашей базой данных будет в недопустимом состоянии (вы, возможно, вычитали сумму из одного счета, но не добавили ее в другой). Итак, если Вы читаете все ваши данные в одном запросе, вам не нужна транзакция.