我正在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)服务的实例,这些实例将同时访问数据库。
那么我将使用哪种事务进行将更新已处理列的访问?以及我需要用于验证记录是否处于活动状态的其他访问使用什么事务?
在这种情况下,如果发生冲突导致不收取费用(我们第二天会收取费用)就可以了。但是至关重要的是,我们不能向某人收取两次费用。而且至关重要的是,在其他操作正在进行事务处理时,读取操作必须立即成功以验证记录是否处于活动状态。
但是保持记录一致是关键。这包括“设置NumUses = NumUses + @ParamNum”的用例,因此它需要将列值的读取,计算和写入视为原子操作。而且,如果我要设置3个列值,它们都将被写在一起。
答案 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
您的第二个问题很广泛。