44 lines
1.8 KiB
C#
44 lines
1.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Runtime.CompilerServices;
|
|
|
|
namespace Umbraco.Core.Persistence
|
|
{
|
|
internal static class DatabaseNodeLockExtensions
|
|
{
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
private static void ValidateDatabase(IUmbracoDatabase database)
|
|
{
|
|
if (database == null)
|
|
throw new ArgumentNullException("database");
|
|
if (database.GetCurrentTransactionIsolationLevel() < IsolationLevel.RepeatableRead)
|
|
throw new InvalidOperationException("A transaction with minimum RepeatableRead isolation level is required.");
|
|
}
|
|
|
|
// updating a record within a repeatable-read transaction gets an exclusive lock on
|
|
// that record which will be kept until the transaction is ended, effectively locking
|
|
// out all other accesses to that record - thus obtaining an exclusive lock over the
|
|
// protected resources.
|
|
public static void AcquireLockNodeWriteLock(this IUmbracoDatabase database, int nodeId)
|
|
{
|
|
ValidateDatabase(database);
|
|
|
|
database.Execute("UPDATE umbracoLock SET value = (CASE WHEN (value=1) THEN -1 ELSE 1 END) WHERE id=@id",
|
|
new { @id = nodeId });
|
|
}
|
|
|
|
// reading a record within a repeatable-read transaction gets a shared lock on
|
|
// that record which will be kept until the transaction is ended, effectively preventing
|
|
// other write accesses to that record - thus obtaining a shared lock over the protected
|
|
// resources.
|
|
public static void AcquireLockNodeReadLock(this IUmbracoDatabase database, int nodeId)
|
|
{
|
|
ValidateDatabase(database);
|
|
|
|
database.ExecuteScalar<int>("SELECT value FROM umbracoLock WHERE id=@id",
|
|
new { @id = nodeId });
|
|
}
|
|
}
|
|
}
|