Moves read/write locking and isolation level to the responsibility of the sql provider based on the db type
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SqlServerCe;
|
||||
using System.Linq;
|
||||
using NPoco;
|
||||
using Umbraco.Core.Persistence.DatabaseAnnotations;
|
||||
@@ -52,6 +54,8 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
return "(" + string.Join("+", args) + ")";
|
||||
}
|
||||
|
||||
public override System.Data.IsolationLevel DefaultIsolationLevel => System.Data.IsolationLevel.RepeatableRead;
|
||||
|
||||
public override string FormatColumnRename(string tableName, string oldName, string newName)
|
||||
{
|
||||
//NOTE Sql CE doesn't support renaming a column, so a new column needs to be created, then copy data and finally remove old column
|
||||
@@ -152,6 +156,39 @@ where table_name=@0 and column_name=@1", tableName, columnName).FirstOrDefault()
|
||||
return result > 0;
|
||||
}
|
||||
|
||||
public override void WriteLock(IDatabase db, params int[] lockIds)
|
||||
{
|
||||
// soon as we get Database, a transaction is started
|
||||
|
||||
if (db.Transaction.IsolationLevel < IsolationLevel.RepeatableRead)
|
||||
throw new InvalidOperationException("A transaction with minimum RepeatableRead isolation level is required.");
|
||||
|
||||
db.Execute(@"SET LOCK_TIMEOUT 1800;");
|
||||
// *not* using a unique 'WHERE IN' query here because the *order* of lockIds is important to avoid deadlocks
|
||||
foreach (var lockId in lockIds)
|
||||
{
|
||||
var i = db.Execute(@"UPDATE umbracoLock SET value = value*-1 WHERE id=@id", new { id = lockId });
|
||||
if (i == 0) // ensure we are actually locking!
|
||||
throw new Exception($"LockObject with id={lockId} does not exist.");
|
||||
}
|
||||
}
|
||||
|
||||
public override void ReadLock(IDatabase db, params int[] lockIds)
|
||||
{
|
||||
// soon as we get Database, a transaction is started
|
||||
|
||||
if (db.Transaction.IsolationLevel < IsolationLevel.RepeatableRead)
|
||||
throw new InvalidOperationException("A transaction with minimum RepeatableRead isolation level is required.");
|
||||
|
||||
// *not* using a unique 'WHERE IN' query here because the *order* of lockIds is important to avoid deadlocks
|
||||
foreach (var lockId in lockIds)
|
||||
{
|
||||
var i = db.ExecuteScalar<int?>("SELECT value FROM umbracoLock WHERE id=@id", new { id = lockId });
|
||||
if (i == null) // ensure we are actually locking!
|
||||
throw new Exception($"LockObject with id={lockId} does not exist.");
|
||||
}
|
||||
}
|
||||
|
||||
protected override string FormatIdentity(ColumnDefinition column)
|
||||
{
|
||||
return column.IsIdentity ? GetIdentityString(column) : string.Empty;
|
||||
|
||||
Reference in New Issue
Block a user