Как мне установить правильный уровень транзакции? - PullRequest
0 голосов
/ 13 сентября 2018

Я использую Dapper на ADO.NET.Поэтому в настоящее время я делаю следующее:

using (IDbConnection conn = new SqlConnection("MyConnectionString")))
{
conn.Open());
using (IDbTransaction transaction = conn.BeginTransaction())
{
// ...

Однако существуют различные уровни транзакций, которые могут быть установлены. Я думаю, что это различные настройки.

Мой первый вопрос: как мне установить уровень транзакции (где я использую Dapper)?

Мой второй вопрос: чтоправильный уровень для каждого из следующих случаев?В каждом из этих случаев у нас есть несколько запущенных служб веб-работника (Azure), которые будут одновременно работать с БД.

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

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

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

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

Но это ключ к тому, чтобы запись оставалась последовательной.И это включает в себя вариант использования «set NumUses = NumUses + @ParamNum», поэтому он должен рассматривать чтение, вычисление и запись значения столбца как атомарное действие.И если я устанавливаю 3 значения столбца, они все записываются вместе.

1 Ответ

0 голосов
/ 14 сентября 2018

1) Предполагая, что процесс выставления счетов-фактур представляет собой SP с несколькими утверждениями, лучше всего создать еще одну таблицу «lock» для хранения факта, что работа по выставлению счетов уже выполняется, например,

CREATE TABLE InvoicingJob( JobStarted DATETIME, IsRunning BIT NOT NULL )

-- Table will only ever have one record
INSERT INTO InvoicingJob
SELECT NULL, 0


EXEC InvoicingProcess

ALTER PROCEDURE InvoicingProcess
AS
BEGIN
    DECLARE @InvoicingJob TABLE( IsRunning BIT )

    -- Try to aquire lock
    UPDATE InvoicingJob WITH( TABLOCK )
    SET JobStarted = GETDATE(), IsRunning = 1
    OUTPUT INSERTED.IsRunning INTO @InvoicingJob( IsRunning )
    WHERE IsRunning = 0
        -- job has been running for more than a day i.e. likely crashed without releasing a lock
        -- OR ( IsRunning = 1 AND JobStarted <= DATEADD( DAY, -1, GETDATE()) 

    IF NOT EXISTS( SELECT * FROM @InvoicingJob )
    BEGIN
        PRINT 'Another Job is already running'
        RETURN
    END
    ELSE
        RAISERROR( 'Start Job', 0, 0 ) WITH NOWAIT


    -- Do invoicing tasks
    WAITFOR DELAY '00:01:00' -- to simulate execution time

    -- Release lock
    UPDATE InvoicingJob
    SET IsRunning = 0
END

2)как работают транзакции: https://docs.microsoft.com/en-us/sql/t-sql/language-elements/transactions-transact-sql?view=sql-server-2017

https://docs.microsoft.com/en-us/sql/t-sql/statements/set-transaction-isolation-level-transact-sql?view=sql-server-2017

Ваш второй вопрос довольно широкий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...