如何设置正确的交易级别?

时间:2018-09-13 03:07:00

标签: sql-server ado.net dapper isolation-level

我正在ADO.NET上使用Dapper。因此,目前我正在执行以下操作:

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

但是,可以设置各种级别的事务。 I think this is the various settings.

我的第一个问题是如何设置交易级别(使用Dapper的位置)?

我的第二个问题是以下每种情况的正确水平是多少?在每种情况下,我们都会运行多个运行Web Worker(Azure)服务的实例,这些实例将同时访问数据库。

  1. 我需要按月收取订阅费用。因此,在交易中,我需要读取记录,如果需要收费,请创建发票记录并将该记录标记为已处理。出于相同目的对该记录的任何其他读取都将失败。但是,只要使用该记录来验证该记录是否处于活动状态,就需要对该记录进行任何其他读取。

那么我将使用哪种事务进行将更新已处理列的访问?以及我需要用于验证记录是否处于活动状态的其他访问使用什么事务?

在这种情况下,如果发生冲突导致不收取费用(我们第二天会收取费用)就可以了。但是至关重要的是,我们不能向某人收取两次费用。而且至关重要的是,在其他操作正在进行事务处理时,读取操作必须立即成功以验证记录是否处于活动状态。

  1. 我需要更新仅设置几列的记录。一种用例是我为用户记录设置了新的密码哈希。如果在此期间发生其他访问(删除记录除外)也很好(我认为这是唯一的问题用例)。如果另一个Web服务也在更新,则这是用户在2个地方同时执行此操作的问题。

但是保持记录一致是关键。这包括“设置NumUses = NumUses + @ParamNum”的用例,因此它需要将列值的读取,计算和写入视为原子操作。而且,如果我要设置3个列值,它们都将被写在一起。

1 个答案:

答案 0 :(得分:1)

1)假设开票流程是一个包含多个语句的SP,您最好的选择是创建另一个“锁”表来存储开票作业已经在运行的事实。

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

您的第二个问题很广泛。