在提交事务和 (UPDLOCK, HOLDLOCK) 之前返回一个值
Returning a value before committing transaction and (UPDLOCK, HOLDLOCK)
我需要检查记录是否存在 - 如果存在:那么 returns 它的 ID,如果不存在:创建一个新记录和 returns 它的 ID。我在 SELECT
中使用 WITH (UPDLOCK, HOLDLOCK)
来防止重复(它会创建锁)。请问如果数据库中存在一条实现锁的记录是否要提交事务?
using (SqlConnection connection = new SqlConnection("..."))
{
await connection.OpenAsync();
using (var transaction = connection.BeginTransaction())
{
var locationId = await connection.QueryFirstOrDefaultAsync<int?>(
"SELECT id
FROM Locations WITH (UPDLOCK, HOLDLOCK)
WHERE regionId = @RegionId", new { RegionId = 1 }, transaction: transaction
);
if (locationId.HasValue)
{
//transaction.Commit(); // should I commit the transaction here?
return locationId.Value;
}
var location = new Location()
{
Name = "test",
RegionId = 1
};
var newLocationid = await connection.InsertAsync<int>(location, transaction);
transaction.Commit();
return newLocationid;
}
}
should I commit the transaction here?
是的。否则它会在 using 块完成时回滚。在这种特殊情况下这无关紧要,但最好明确说明。如果这个交易是一个更大交易的一部分,整个事情就会回滚。
这里不需要交易。
using (SqlConnection connection = new SqlConnection("..."))
{
await connection.OpenAsync();
/* The lock hints you had here makes no sense. */
var locationId = await connection.QueryFirstOrDefaultAsync<int?>(
"SELECT id
FROM Locations
WHERE regionId = @RegionId", new { RegionId = 1 }
);
if (locationId.HasValue)
{
return locationId.Value;
}
var location = new Location()
{
Name = "test",
RegionId = 1
};
/* INSERT has an implicit transaction
only need to use a transaction if you have multiple DML statements (i.e. INSERT, UPDATE or DELETE statments) */
var newLocationid = await connection.InsertAsync<int>(location);
return newLocationid;
}
}
好吧,您不必在查询时开始交易。您可以按如下方式重写代码:
using (SqlConnection connection = new SqlConnection("..."))
{
await connection.OpenAsync();
var locationId = await connection.QueryFirstOrDefaultAsync<int?>(
"SELECT id
FROM Locations WITH (UPDLOCK, HOLDLOCK)
WHERE regionId = @RegionId", new { RegionId = 1 });
if (locationId.HasValue)
{
return locationId.Value;
}
using (var transaction = connection.BeginTransaction())
{
var location = new Location()
{
Name = "test",
RegionId = 1
};
var newLocationid = await connection.InsertAsync<int>(location, transaction);
transaction.Commit();
}
return newLocationid;
}
我需要检查记录是否存在 - 如果存在:那么 returns 它的 ID,如果不存在:创建一个新记录和 returns 它的 ID。我在 SELECT
中使用 WITH (UPDLOCK, HOLDLOCK)
来防止重复(它会创建锁)。请问如果数据库中存在一条实现锁的记录是否要提交事务?
using (SqlConnection connection = new SqlConnection("..."))
{
await connection.OpenAsync();
using (var transaction = connection.BeginTransaction())
{
var locationId = await connection.QueryFirstOrDefaultAsync<int?>(
"SELECT id
FROM Locations WITH (UPDLOCK, HOLDLOCK)
WHERE regionId = @RegionId", new { RegionId = 1 }, transaction: transaction
);
if (locationId.HasValue)
{
//transaction.Commit(); // should I commit the transaction here?
return locationId.Value;
}
var location = new Location()
{
Name = "test",
RegionId = 1
};
var newLocationid = await connection.InsertAsync<int>(location, transaction);
transaction.Commit();
return newLocationid;
}
}
should I commit the transaction here?
是的。否则它会在 using 块完成时回滚。在这种特殊情况下这无关紧要,但最好明确说明。如果这个交易是一个更大交易的一部分,整个事情就会回滚。
这里不需要交易。
using (SqlConnection connection = new SqlConnection("..."))
{
await connection.OpenAsync();
/* The lock hints you had here makes no sense. */
var locationId = await connection.QueryFirstOrDefaultAsync<int?>(
"SELECT id
FROM Locations
WHERE regionId = @RegionId", new { RegionId = 1 }
);
if (locationId.HasValue)
{
return locationId.Value;
}
var location = new Location()
{
Name = "test",
RegionId = 1
};
/* INSERT has an implicit transaction
only need to use a transaction if you have multiple DML statements (i.e. INSERT, UPDATE or DELETE statments) */
var newLocationid = await connection.InsertAsync<int>(location);
return newLocationid;
}
}
好吧,您不必在查询时开始交易。您可以按如下方式重写代码:
using (SqlConnection connection = new SqlConnection("..."))
{
await connection.OpenAsync();
var locationId = await connection.QueryFirstOrDefaultAsync<int?>(
"SELECT id
FROM Locations WITH (UPDLOCK, HOLDLOCK)
WHERE regionId = @RegionId", new { RegionId = 1 });
if (locationId.HasValue)
{
return locationId.Value;
}
using (var transaction = connection.BeginTransaction())
{
var location = new Location()
{
Name = "test",
RegionId = 1
};
var newLocationid = await connection.InsertAsync<int>(location, transaction);
transaction.Commit();
}
return newLocationid;
}