From ffd6f3e6a85ad6ea4a6a6d303e3edce88edef644 Mon Sep 17 00:00:00 2001
From: gliljas
Date: Mon, 10 Apr 2023 23:43:45 +0200
Subject: [PATCH 1/5] Support multitenancy in id generators
---
.../HiLoForcedTableSequenceTest.cs | 26 ++--
.../PooledForcedTableSequenceTest.cs | 22 +--
.../Async/IdGen/Enhanced/OptimizerTests.cs | 2 +-
.../Enhanced/Sequence/HiLoSequenceTest.cs | 23 +--
.../Enhanced/Sequence/PooledSequenceTest.cs | 22 +--
.../Async/IdGen/Enhanced/SourceMock.cs | 2 +-
.../IdGen/Enhanced/Table/HiLoTableTest.cs | 21 ++-
.../IdGen/Enhanced/Table/PooledLoTableTest.cs | 17 +-
.../IdGen/Enhanced/Table/PooledTableTest.cs | 18 ++-
.../HiLoForcedTableSequenceTest.cs | 26 ++--
.../PooledForcedTableSequenceTest.cs | 22 +--
.../IdGen/Enhanced/OptimizerTests.cs | 4 +-
.../Enhanced/Sequence/HiLoSequenceTest.cs | 23 +--
.../Enhanced/Sequence/PooledSequenceTest.cs | 22 +--
.../IdGen/Enhanced/SourceMock.cs | 13 +-
.../IdGen/Enhanced/Table/HiLoTableTest.cs | 21 ++-
.../IdGen/Enhanced/Table/PooledLoTableTest.cs | 17 +-
.../IdGen/Enhanced/Table/PooledTableTest.cs | 18 ++-
.../MultiTenancy/TestCaseWithMultiTenancy.cs | 60 +++++++
src/NHibernate.Test/TestCase.cs | 2 +
.../Async/Id/Enhanced/IAccessCallback.cs | 2 +-
.../Async/Id/Enhanced/OptimizerFactory.cs | 65 ++++----
.../Async/Id/Enhanced/TableGenerator.cs | 10 +-
.../Async/Id/SequenceHiLoGenerator.cs | 11 +-
src/NHibernate/Async/Id/TableGenerator.cs | 4 +-
src/NHibernate/Async/Id/TableHiLoGenerator.cs | 11 +-
src/NHibernate/Id/Enhanced/IAccessCallback.cs | 7 +-
.../Id/Enhanced/OptimizerFactory.cs | 147 ++++++++++++------
.../Id/Enhanced/SequenceStructure.cs | 2 +
src/NHibernate/Id/Enhanced/TableGenerator.cs | 20 +--
src/NHibernate/Id/Enhanced/TableStructure.cs | 2 +
src/NHibernate/Id/SequenceHiLoGenerator.cs | 24 ++-
src/NHibernate/Id/TableGenerator.cs | 4 +-
src/NHibernate/Id/TableHiLoGenerator.cs | 65 +++++++-
34 files changed, 506 insertions(+), 249 deletions(-)
create mode 100644 src/NHibernate.Test/MultiTenancy/TestCaseWithMultiTenancy.cs
diff --git a/src/NHibernate.Test/Async/IdGen/Enhanced/Forcedtable/HiLoForcedTableSequenceTest.cs b/src/NHibernate.Test/Async/IdGen/Enhanced/Forcedtable/HiLoForcedTableSequenceTest.cs
index 9aff73e4e83..abf9104e83f 100644
--- a/src/NHibernate.Test/Async/IdGen/Enhanced/Forcedtable/HiLoForcedTableSequenceTest.cs
+++ b/src/NHibernate.Test/Async/IdGen/Enhanced/Forcedtable/HiLoForcedTableSequenceTest.cs
@@ -8,16 +8,20 @@
//------------------------------------------------------------------------------
-using NUnit.Framework;
using NHibernate.Id.Enhanced;
-using System.Collections;
+using NHibernate.Test.MultiTenancy;
+using NUnit.Framework;
namespace NHibernate.Test.IdGen.Enhanced.Forcedtable
{
using System.Threading.Tasks;
- [TestFixture]
- public class HiLoForcedTableSequenceTestAsync : TestCase
+ [TestFixture(null)]
+ [TestFixture("test")]
+ public class HiLoForcedTableSequenceTestAsync : TestCaseWithMultiTenancy
{
+ public HiLoForcedTableSequenceTestAsync(string tenantIdentifier) : base(tenantIdentifier)
+ {
+ }
protected override string[] Mappings
{
get { return new[] { "IdGen.Enhanced.Forcedtable.HiLo.hbm.xml" }; }
@@ -54,9 +58,9 @@ public async Task TestNormalBoundaryAsync()
long expectedId = i + 1;
Assert.That(entities[i].Id, Is.EqualTo(expectedId));
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(1)); // initialization
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(1)); // initialization
- Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
- Assert.That(optimizer.HiValue, Is.EqualTo(increment + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(1)); // initialization
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
+ Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo(increment + 1));
}
// now force a "clock over"
@@ -64,9 +68,9 @@ public async Task TestNormalBoundaryAsync()
await (session.SaveAsync(entities[increment]));
Assert.That(entities[optimizer.IncrementSize].Id, Is.EqualTo(optimizer.IncrementSize + 1));
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(2)); // initialization + clock-over
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(2)); // initialization + clock-over
- Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
- Assert.That(optimizer.HiValue, Is.EqualTo(increment * 2 + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(2)); // initialization + clock-over
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
+ Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo(increment * 2 + 1));
await (transaction.CommitAsync());
}
@@ -85,4 +89,4 @@ public async Task TestNormalBoundaryAsync()
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/NHibernate.Test/Async/IdGen/Enhanced/Forcedtable/PooledForcedTableSequenceTest.cs b/src/NHibernate.Test/Async/IdGen/Enhanced/Forcedtable/PooledForcedTableSequenceTest.cs
index f792da88124..9f5f3a4168a 100644
--- a/src/NHibernate.Test/Async/IdGen/Enhanced/Forcedtable/PooledForcedTableSequenceTest.cs
+++ b/src/NHibernate.Test/Async/IdGen/Enhanced/Forcedtable/PooledForcedTableSequenceTest.cs
@@ -8,16 +8,20 @@
//------------------------------------------------------------------------------
-using NUnit.Framework;
using NHibernate.Id.Enhanced;
-using System.Collections;
+using NHibernate.Test.MultiTenancy;
+using NUnit.Framework;
namespace NHibernate.Test.IdGen.Enhanced.Forcedtable
{
using System.Threading.Tasks;
- [TestFixture]
- public class PooledForcedTableSequenceTestAsync : TestCase
+ [TestFixture(null)]
+ [TestFixture("test")]
+ public class PooledForcedTableSequenceTestAsync : TestCaseWithMultiTenancy
{
+ public PooledForcedTableSequenceTestAsync(string tenantIdentifier) : base(tenantIdentifier)
+ {
+ }
protected override string[] Mappings
{
get { return new[] { "IdGen.Enhanced.Forcedtable.Pooled.hbm.xml" }; }
@@ -55,8 +59,8 @@ public async Task TestNormalBoundaryAsync()
Assert.That(entities[i].Id, Is.EqualTo(expectedId));
// NOTE : initialization calls table twice
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(2)); // initialization
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment + 1)); // initialization
- Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment + 1)); // initialization
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
}
// now force a "clock over"
@@ -66,8 +70,8 @@ public async Task TestNormalBoundaryAsync()
Assert.That(entities[optimizer.IncrementSize].Id, Is.EqualTo(optimizer.IncrementSize + 1));
// initialization (2) + clock over
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(3));
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment*2 + 1));
- Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment*2 + 1));
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
await (transaction.CommitAsync());
}
@@ -86,4 +90,4 @@ public async Task TestNormalBoundaryAsync()
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/NHibernate.Test/Async/IdGen/Enhanced/OptimizerTests.cs b/src/NHibernate.Test/Async/IdGen/Enhanced/OptimizerTests.cs
index e7e5c23fad0..a047e3aec35 100644
--- a/src/NHibernate.Test/Async/IdGen/Enhanced/OptimizerTests.cs
+++ b/src/NHibernate.Test/Async/IdGen/Enhanced/OptimizerTests.cs
@@ -8,8 +8,8 @@
//------------------------------------------------------------------------------
-using NUnit.Framework;
using NHibernate.Id.Enhanced;
+using NUnit.Framework;
namespace NHibernate.Test.IdGen.Enhanced
{
diff --git a/src/NHibernate.Test/Async/IdGen/Enhanced/Sequence/HiLoSequenceTest.cs b/src/NHibernate.Test/Async/IdGen/Enhanced/Sequence/HiLoSequenceTest.cs
index cb185e72c6f..4b1606cf330 100644
--- a/src/NHibernate.Test/Async/IdGen/Enhanced/Sequence/HiLoSequenceTest.cs
+++ b/src/NHibernate.Test/Async/IdGen/Enhanced/Sequence/HiLoSequenceTest.cs
@@ -11,13 +11,18 @@
using System.Collections;
using NUnit.Framework;
using NHibernate.Id.Enhanced;
+using NHibernate.Test.MultiTenancy;
namespace NHibernate.Test.IdGen.Enhanced.Sequence
{
using System.Threading.Tasks;
- [TestFixture]
- public class HiLoSequenceTestAsync : TestCase
+ [TestFixture(null)]
+ [TestFixture("test")]
+ public class HiLoSequenceTestAsync : TestCaseWithMultiTenancy
{
+ public HiLoSequenceTestAsync(string tenantIdentifier) : base(tenantIdentifier)
+ {
+ }
protected override string[] Mappings
{
get { return new[] { "IdGen.Enhanced.Sequence.HiLo.hbm.xml" }; }
@@ -51,18 +56,18 @@ public async Task TestNormalBoundaryAsync()
entities[i] = new Entity("" + (i + 1));
await (session.SaveAsync(entities[i]));
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(1)); // initialization
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(1)); // initialization
- Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
- Assert.That(optimizer.HiValue, Is.EqualTo(increment + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(1)); // initialization
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
+ Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo(increment + 1));
}
// now force a "clock over"
entities[increment] = new Entity("" + increment);
await (session.SaveAsync(entities[increment]));
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(2));
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(2));
- Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
- Assert.That(optimizer.HiValue, Is.EqualTo(increment * 2 + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(2));
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
+ Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo(increment * 2 + 1));
await (transaction.CommitAsync());
}
@@ -80,4 +85,4 @@ public async Task TestNormalBoundaryAsync()
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/NHibernate.Test/Async/IdGen/Enhanced/Sequence/PooledSequenceTest.cs b/src/NHibernate.Test/Async/IdGen/Enhanced/Sequence/PooledSequenceTest.cs
index 7d0d4d11763..1d06ae11d89 100644
--- a/src/NHibernate.Test/Async/IdGen/Enhanced/Sequence/PooledSequenceTest.cs
+++ b/src/NHibernate.Test/Async/IdGen/Enhanced/Sequence/PooledSequenceTest.cs
@@ -8,16 +8,20 @@
//------------------------------------------------------------------------------
-using System.Collections;
-using NUnit.Framework;
using NHibernate.Id.Enhanced;
+using NHibernate.Test.MultiTenancy;
+using NUnit.Framework;
namespace NHibernate.Test.IdGen.Enhanced.Sequence
{
using System.Threading.Tasks;
- [TestFixture]
- public class PooledSequenceTestAsync : TestCase
+ [TestFixture(null)]
+ [TestFixture("test")]
+ public class PooledSequenceTestAsync : TestCaseWithMultiTenancy
{
+ public PooledSequenceTestAsync(string tenantIdentifier) : base(tenantIdentifier)
+ {
+ }
protected override string[] Mappings
{
get { return new[] { "IdGen.Enhanced.Sequence.Pooled.hbm.xml" }; }
@@ -51,16 +55,16 @@ public async Task TestNormalBoundaryAsync()
entities[i] = new Entity("" + (i + 1));
await (session.SaveAsync(entities[i]));
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(2)); // initialization calls seq twice
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment + 1)); // initialization calls seq twice
- Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment + 1)); // initialization calls seq twice
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
}
// now force a "clock over"
entities[increment] = new Entity("" + increment);
await (session.SaveAsync(entities[increment]));
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(3)); // initialization (2) + clock over
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment * 2 + 1)); // initialization (2) + clock over
- Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment * 2 + 1)); // initialization (2) + clock over
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
await (transaction.CommitAsync());
}
@@ -79,4 +83,4 @@ public async Task TestNormalBoundaryAsync()
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/NHibernate.Test/Async/IdGen/Enhanced/SourceMock.cs b/src/NHibernate.Test/Async/IdGen/Enhanced/SourceMock.cs
index 0f9615a2ccd..85fc9520c87 100644
--- a/src/NHibernate.Test/Async/IdGen/Enhanced/SourceMock.cs
+++ b/src/NHibernate.Test/Async/IdGen/Enhanced/SourceMock.cs
@@ -46,4 +46,4 @@ public Task GetNextValueAsync(CancellationToken cancellationToken)
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/NHibernate.Test/Async/IdGen/Enhanced/Table/HiLoTableTest.cs b/src/NHibernate.Test/Async/IdGen/Enhanced/Table/HiLoTableTest.cs
index 962460f90e0..2e53c916aea 100644
--- a/src/NHibernate.Test/Async/IdGen/Enhanced/Table/HiLoTableTest.cs
+++ b/src/NHibernate.Test/Async/IdGen/Enhanced/Table/HiLoTableTest.cs
@@ -10,14 +10,19 @@
using System.Collections;
using NHibernate.Id.Enhanced;
+using NHibernate.Test.MultiTenancy;
using NUnit.Framework;
namespace NHibernate.Test.IdGen.Enhanced.Table
{
using System.Threading.Tasks;
- [TestFixture]
- public class HiLoTableTestAsync : TestCase
+ [TestFixture(null)]
+ [TestFixture("test")]
+ public class HiLoTableTestAsync : TestCaseWithMultiTenancy
{
+ public HiLoTableTestAsync(string tenantIdentifier) : base(tenantIdentifier)
+ {
+ }
protected override string[] Mappings
{
get { return new[] { "IdGen.Enhanced.Table.HiLo.hbm.xml" }; }
@@ -50,18 +55,18 @@ public async Task TestNormalBoundaryAsync()
entities[i] = new Entity("" + (i + 1));
await (s.SaveAsync(entities[i]));
Assert.That(generator.TableAccessCount, Is.EqualTo(1)); // initialization
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(1)); // initialization
- Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
- Assert.That(optimizer.HiValue, Is.EqualTo(increment + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(1)); // initialization
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
+ Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo(increment + 1));
}
// now force a "clock over"
entities[increment] = new Entity("" + increment);
await (s.SaveAsync(entities[increment]));
Assert.That(generator.TableAccessCount, Is.EqualTo(2));
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(2));
- Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
- Assert.That(optimizer.HiValue, Is.EqualTo((increment * 2) + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(2));
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
+ Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo((increment * 2) + 1));
await (transaction.CommitAsync());
}
diff --git a/src/NHibernate.Test/Async/IdGen/Enhanced/Table/PooledLoTableTest.cs b/src/NHibernate.Test/Async/IdGen/Enhanced/Table/PooledLoTableTest.cs
index d721443bdd6..af309699513 100644
--- a/src/NHibernate.Test/Async/IdGen/Enhanced/Table/PooledLoTableTest.cs
+++ b/src/NHibernate.Test/Async/IdGen/Enhanced/Table/PooledLoTableTest.cs
@@ -10,14 +10,19 @@
using System.Collections;
using NHibernate.Id.Enhanced;
+using NHibernate.Test.MultiTenancy;
using NUnit.Framework;
namespace NHibernate.Test.IdGen.Enhanced.Table
{
using System.Threading.Tasks;
- [TestFixture]
- public class PooledLoTableTestAsync : TestCase
+ [TestFixture(null)]
+ [TestFixture("test")]
+ public class PooledLoTableTestAsync : TestCaseWithMultiTenancy
{
+ public PooledLoTableTestAsync(string tenantIdentifier) : base(tenantIdentifier)
+ {
+ }
protected override string[] Mappings
{
get { return new[] { "IdGen.Enhanced.Table.PooledLo.hbm.xml" }; }
@@ -50,16 +55,16 @@ public async Task TestNormalBoundaryAsync()
entities[i] = new Entity("" + (i + 1));
await (s.SaveAsync(entities[i]));
Assert.That(generator.TableAccessCount, Is.EqualTo(1)); // initialization
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(1)); // initialization
- Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(1)); // initialization
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
}
// now force a "clock over"
entities[increment] = new Entity("" + increment);
await (s.SaveAsync(entities[increment]));
Assert.That(generator.TableAccessCount, Is.EqualTo(2));
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment + 1));
- Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment + 1));
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
await (transaction.CommitAsync());
}
diff --git a/src/NHibernate.Test/Async/IdGen/Enhanced/Table/PooledTableTest.cs b/src/NHibernate.Test/Async/IdGen/Enhanced/Table/PooledTableTest.cs
index 00c921da834..15be48dccaa 100644
--- a/src/NHibernate.Test/Async/IdGen/Enhanced/Table/PooledTableTest.cs
+++ b/src/NHibernate.Test/Async/IdGen/Enhanced/Table/PooledTableTest.cs
@@ -8,16 +8,20 @@
//------------------------------------------------------------------------------
-using System.Collections;
using NHibernate.Id.Enhanced;
+using NHibernate.Test.MultiTenancy;
using NUnit.Framework;
namespace NHibernate.Test.IdGen.Enhanced.Table
{
using System.Threading.Tasks;
- [TestFixture]
- public class PooledTableTestAsync : TestCase
+ [TestFixture(null)]
+ [TestFixture("test")]
+ public class PooledTableTestAsync : TestCaseWithMultiTenancy
{
+ public PooledTableTestAsync(string tenantIdentifier) : base(tenantIdentifier)
+ {
+ }
protected override string[] Mappings
{
get { return new[] { "IdGen.Enhanced.Table.Pooled.hbm.xml" }; }
@@ -50,16 +54,16 @@ public async Task TestNormalBoundaryAsync()
entities[i] = new Entity("" + (i + 1));
await (s.SaveAsync(entities[i]));
Assert.That(generator.TableAccessCount, Is.EqualTo(2)); // initialization calls seq twice
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment + 1)); // initialization calls seq twice
- Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment + 1)); // initialization calls seq twice
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
}
// now force a "clock over"
entities[increment] = new Entity("" + increment);
await (s.SaveAsync(entities[increment]));
Assert.That(generator.TableAccessCount, Is.EqualTo(3)); // initialization (2) + clock over
- Assert.That(optimizer.LastSourceValue, Is.EqualTo((increment * 2) + 1)); // initialization (2) + clock over
- Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo((increment * 2) + 1)); // initialization (2) + clock over
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
await (transaction.CommitAsync());
}
diff --git a/src/NHibernate.Test/IdGen/Enhanced/Forcedtable/HiLoForcedTableSequenceTest.cs b/src/NHibernate.Test/IdGen/Enhanced/Forcedtable/HiLoForcedTableSequenceTest.cs
index c2ba2b1f589..e8647f3858f 100644
--- a/src/NHibernate.Test/IdGen/Enhanced/Forcedtable/HiLoForcedTableSequenceTest.cs
+++ b/src/NHibernate.Test/IdGen/Enhanced/Forcedtable/HiLoForcedTableSequenceTest.cs
@@ -1,12 +1,16 @@
-using NUnit.Framework;
using NHibernate.Id.Enhanced;
-using System.Collections;
+using NHibernate.Test.MultiTenancy;
+using NUnit.Framework;
namespace NHibernate.Test.IdGen.Enhanced.Forcedtable
{
- [TestFixture]
- public class HiLoForcedTableSequenceTest : TestCase
+ [TestFixture(null)]
+ [TestFixture("test")]
+ public class HiLoForcedTableSequenceTest : TestCaseWithMultiTenancy
{
+ public HiLoForcedTableSequenceTest(string tenantIdentifier) : base(tenantIdentifier)
+ {
+ }
protected override string[] Mappings
{
get { return new[] { "IdGen.Enhanced.Forcedtable.HiLo.hbm.xml" }; }
@@ -43,9 +47,9 @@ public void TestNormalBoundary()
long expectedId = i + 1;
Assert.That(entities[i].Id, Is.EqualTo(expectedId));
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(1)); // initialization
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(1)); // initialization
- Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
- Assert.That(optimizer.HiValue, Is.EqualTo(increment + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(1)); // initialization
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
+ Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo(increment + 1));
}
// now force a "clock over"
@@ -53,9 +57,9 @@ public void TestNormalBoundary()
session.Save(entities[increment]);
Assert.That(entities[optimizer.IncrementSize].Id, Is.EqualTo(optimizer.IncrementSize + 1));
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(2)); // initialization + clock-over
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(2)); // initialization + clock-over
- Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
- Assert.That(optimizer.HiValue, Is.EqualTo(increment * 2 + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(2)); // initialization + clock-over
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
+ Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo(increment * 2 + 1));
transaction.Commit();
}
@@ -74,4 +78,4 @@ public void TestNormalBoundary()
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/NHibernate.Test/IdGen/Enhanced/Forcedtable/PooledForcedTableSequenceTest.cs b/src/NHibernate.Test/IdGen/Enhanced/Forcedtable/PooledForcedTableSequenceTest.cs
index 91839abf07f..39598c9d591 100644
--- a/src/NHibernate.Test/IdGen/Enhanced/Forcedtable/PooledForcedTableSequenceTest.cs
+++ b/src/NHibernate.Test/IdGen/Enhanced/Forcedtable/PooledForcedTableSequenceTest.cs
@@ -1,12 +1,16 @@
-using NUnit.Framework;
using NHibernate.Id.Enhanced;
-using System.Collections;
+using NHibernate.Test.MultiTenancy;
+using NUnit.Framework;
namespace NHibernate.Test.IdGen.Enhanced.Forcedtable
{
- [TestFixture]
- public class PooledForcedTableSequenceTest : TestCase
+ [TestFixture(null)]
+ [TestFixture("test")]
+ public class PooledForcedTableSequenceTest : TestCaseWithMultiTenancy
{
+ public PooledForcedTableSequenceTest(string tenantIdentifier) : base(tenantIdentifier)
+ {
+ }
protected override string[] Mappings
{
get { return new[] { "IdGen.Enhanced.Forcedtable.Pooled.hbm.xml" }; }
@@ -44,8 +48,8 @@ public void TestNormalBoundary()
Assert.That(entities[i].Id, Is.EqualTo(expectedId));
// NOTE : initialization calls table twice
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(2)); // initialization
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment + 1)); // initialization
- Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment + 1)); // initialization
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
}
// now force a "clock over"
@@ -55,8 +59,8 @@ public void TestNormalBoundary()
Assert.That(entities[optimizer.IncrementSize].Id, Is.EqualTo(optimizer.IncrementSize + 1));
// initialization (2) + clock over
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(3));
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment*2 + 1));
- Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment*2 + 1));
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
transaction.Commit();
}
@@ -75,4 +79,4 @@ public void TestNormalBoundary()
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/NHibernate.Test/IdGen/Enhanced/OptimizerTests.cs b/src/NHibernate.Test/IdGen/Enhanced/OptimizerTests.cs
index 8f0fd01986f..90842a1048e 100644
--- a/src/NHibernate.Test/IdGen/Enhanced/OptimizerTests.cs
+++ b/src/NHibernate.Test/IdGen/Enhanced/OptimizerTests.cs
@@ -1,5 +1,5 @@
-using NUnit.Framework;
-using NHibernate.Id.Enhanced;
+using NHibernate.Id.Enhanced;
+using NUnit.Framework;
namespace NHibernate.Test.IdGen.Enhanced
{
diff --git a/src/NHibernate.Test/IdGen/Enhanced/Sequence/HiLoSequenceTest.cs b/src/NHibernate.Test/IdGen/Enhanced/Sequence/HiLoSequenceTest.cs
index 3cac164ec72..7cd6161bc02 100644
--- a/src/NHibernate.Test/IdGen/Enhanced/Sequence/HiLoSequenceTest.cs
+++ b/src/NHibernate.Test/IdGen/Enhanced/Sequence/HiLoSequenceTest.cs
@@ -1,12 +1,17 @@
using System.Collections;
using NUnit.Framework;
using NHibernate.Id.Enhanced;
+using NHibernate.Test.MultiTenancy;
namespace NHibernate.Test.IdGen.Enhanced.Sequence
{
- [TestFixture]
- public class HiLoSequenceTest : TestCase
+ [TestFixture(null)]
+ [TestFixture("test")]
+ public class HiLoSequenceTest : TestCaseWithMultiTenancy
{
+ public HiLoSequenceTest(string tenantIdentifier) : base(tenantIdentifier)
+ {
+ }
protected override string[] Mappings
{
get { return new[] { "IdGen.Enhanced.Sequence.HiLo.hbm.xml" }; }
@@ -40,18 +45,18 @@ public void TestNormalBoundary()
entities[i] = new Entity("" + (i + 1));
session.Save(entities[i]);
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(1)); // initialization
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(1)); // initialization
- Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
- Assert.That(optimizer.HiValue, Is.EqualTo(increment + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(1)); // initialization
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
+ Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo(increment + 1));
}
// now force a "clock over"
entities[increment] = new Entity("" + increment);
session.Save(entities[increment]);
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(2));
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(2));
- Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
- Assert.That(optimizer.HiValue, Is.EqualTo(increment * 2 + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(2));
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
+ Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo(increment * 2 + 1));
transaction.Commit();
}
@@ -69,4 +74,4 @@ public void TestNormalBoundary()
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/NHibernate.Test/IdGen/Enhanced/Sequence/PooledSequenceTest.cs b/src/NHibernate.Test/IdGen/Enhanced/Sequence/PooledSequenceTest.cs
index 3e73cc21a9d..b18c211b7ba 100644
--- a/src/NHibernate.Test/IdGen/Enhanced/Sequence/PooledSequenceTest.cs
+++ b/src/NHibernate.Test/IdGen/Enhanced/Sequence/PooledSequenceTest.cs
@@ -1,12 +1,16 @@
-using System.Collections;
-using NUnit.Framework;
using NHibernate.Id.Enhanced;
+using NHibernate.Test.MultiTenancy;
+using NUnit.Framework;
namespace NHibernate.Test.IdGen.Enhanced.Sequence
{
- [TestFixture]
- public class PooledSequenceTest : TestCase
+ [TestFixture(null)]
+ [TestFixture("test")]
+ public class PooledSequenceTest : TestCaseWithMultiTenancy
{
+ public PooledSequenceTest(string tenantIdentifier) : base(tenantIdentifier)
+ {
+ }
protected override string[] Mappings
{
get { return new[] { "IdGen.Enhanced.Sequence.Pooled.hbm.xml" }; }
@@ -40,16 +44,16 @@ public void TestNormalBoundary()
entities[i] = new Entity("" + (i + 1));
session.Save(entities[i]);
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(2)); // initialization calls seq twice
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment + 1)); // initialization calls seq twice
- Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment + 1)); // initialization calls seq twice
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
}
// now force a "clock over"
entities[increment] = new Entity("" + increment);
session.Save(entities[increment]);
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(3)); // initialization (2) + clock over
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment * 2 + 1)); // initialization (2) + clock over
- Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment * 2 + 1)); // initialization (2) + clock over
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
transaction.Commit();
}
@@ -68,4 +72,4 @@ public void TestNormalBoundary()
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/NHibernate.Test/IdGen/Enhanced/SourceMock.cs b/src/NHibernate.Test/IdGen/Enhanced/SourceMock.cs
index d7fcce2f9ec..3097d3f3814 100644
--- a/src/NHibernate.Test/IdGen/Enhanced/SourceMock.cs
+++ b/src/NHibernate.Test/IdGen/Enhanced/SourceMock.cs
@@ -6,15 +6,20 @@ public partial class SourceMock : IAccessCallback
{
private long _val;
private readonly long _initialValue;
+ private readonly string _tenantId;
private readonly int _increment;
private int _timesCalled;
public SourceMock(long initialValue) : this(initialValue, 1) { }
- public SourceMock(long initialValue, int increment) : this(initialValue, increment, 0) { }
+ public SourceMock(long initialValue, int increment) : this(null, initialValue, increment, 0) { }
- public SourceMock(long initialValue, int increment, int timesCalled)
+ public SourceMock(long initialValue, int increment, int timesCalled): this(null, initialValue, increment, timesCalled)
{
+ }
+ public SourceMock(string tenantId, long initialValue, int increment, int timesCalled)
+ {
+ _tenantId = tenantId;
_increment = increment;
_timesCalled = timesCalled;
@@ -57,6 +62,8 @@ private void InitValue()
_val = _initialValue;
}
+ public string GetTenantIdentifier() => _tenantId;
+
public int TimesCalled
{
get { return _timesCalled; }
@@ -71,4 +78,4 @@ public long CurrentValue
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/NHibernate.Test/IdGen/Enhanced/Table/HiLoTableTest.cs b/src/NHibernate.Test/IdGen/Enhanced/Table/HiLoTableTest.cs
index 878252ce3dd..014788d6570 100644
--- a/src/NHibernate.Test/IdGen/Enhanced/Table/HiLoTableTest.cs
+++ b/src/NHibernate.Test/IdGen/Enhanced/Table/HiLoTableTest.cs
@@ -1,12 +1,17 @@
using System.Collections;
using NHibernate.Id.Enhanced;
+using NHibernate.Test.MultiTenancy;
using NUnit.Framework;
namespace NHibernate.Test.IdGen.Enhanced.Table
{
- [TestFixture]
- public class HiLoTableTest : TestCase
+ [TestFixture(null)]
+ [TestFixture("test")]
+ public class HiLoTableTest : TestCaseWithMultiTenancy
{
+ public HiLoTableTest(string tenantIdentifier) : base(tenantIdentifier)
+ {
+ }
protected override string[] Mappings
{
get { return new[] { "IdGen.Enhanced.Table.HiLo.hbm.xml" }; }
@@ -39,18 +44,18 @@ public void TestNormalBoundary()
entities[i] = new Entity("" + (i + 1));
s.Save(entities[i]);
Assert.That(generator.TableAccessCount, Is.EqualTo(1)); // initialization
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(1)); // initialization
- Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
- Assert.That(optimizer.HiValue, Is.EqualTo(increment + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(1)); // initialization
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
+ Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo(increment + 1));
}
// now force a "clock over"
entities[increment] = new Entity("" + increment);
s.Save(entities[increment]);
Assert.That(generator.TableAccessCount, Is.EqualTo(2));
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(2));
- Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
- Assert.That(optimizer.HiValue, Is.EqualTo((increment * 2) + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(2));
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
+ Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo((increment * 2) + 1));
transaction.Commit();
}
diff --git a/src/NHibernate.Test/IdGen/Enhanced/Table/PooledLoTableTest.cs b/src/NHibernate.Test/IdGen/Enhanced/Table/PooledLoTableTest.cs
index bd5245dbe9a..e56c2fed120 100644
--- a/src/NHibernate.Test/IdGen/Enhanced/Table/PooledLoTableTest.cs
+++ b/src/NHibernate.Test/IdGen/Enhanced/Table/PooledLoTableTest.cs
@@ -1,12 +1,17 @@
using System.Collections;
using NHibernate.Id.Enhanced;
+using NHibernate.Test.MultiTenancy;
using NUnit.Framework;
namespace NHibernate.Test.IdGen.Enhanced.Table
{
- [TestFixture]
- public class PooledLoTableTest : TestCase
+ [TestFixture(null)]
+ [TestFixture("test")]
+ public class PooledLoTableTest : TestCaseWithMultiTenancy
{
+ public PooledLoTableTest(string tenantIdentifier) : base(tenantIdentifier)
+ {
+ }
protected override string[] Mappings
{
get { return new[] { "IdGen.Enhanced.Table.PooledLo.hbm.xml" }; }
@@ -39,16 +44,16 @@ public void TestNormalBoundary()
entities[i] = new Entity("" + (i + 1));
s.Save(entities[i]);
Assert.That(generator.TableAccessCount, Is.EqualTo(1)); // initialization
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(1)); // initialization
- Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(1)); // initialization
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
}
// now force a "clock over"
entities[increment] = new Entity("" + increment);
s.Save(entities[increment]);
Assert.That(generator.TableAccessCount, Is.EqualTo(2));
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment + 1));
- Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment + 1));
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
transaction.Commit();
}
diff --git a/src/NHibernate.Test/IdGen/Enhanced/Table/PooledTableTest.cs b/src/NHibernate.Test/IdGen/Enhanced/Table/PooledTableTest.cs
index 3a7ca042514..4f357bc6066 100644
--- a/src/NHibernate.Test/IdGen/Enhanced/Table/PooledTableTest.cs
+++ b/src/NHibernate.Test/IdGen/Enhanced/Table/PooledTableTest.cs
@@ -1,12 +1,16 @@
-using System.Collections;
using NHibernate.Id.Enhanced;
+using NHibernate.Test.MultiTenancy;
using NUnit.Framework;
namespace NHibernate.Test.IdGen.Enhanced.Table
{
- [TestFixture]
- public class PooledTableTest : TestCase
+ [TestFixture(null)]
+ [TestFixture("test")]
+ public class PooledTableTest : TestCaseWithMultiTenancy
{
+ public PooledTableTest(string tenantIdentifier) : base(tenantIdentifier)
+ {
+ }
protected override string[] Mappings
{
get { return new[] { "IdGen.Enhanced.Table.Pooled.hbm.xml" }; }
@@ -39,16 +43,16 @@ public void TestNormalBoundary()
entities[i] = new Entity("" + (i + 1));
s.Save(entities[i]);
Assert.That(generator.TableAccessCount, Is.EqualTo(2)); // initialization calls seq twice
- Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment + 1)); // initialization calls seq twice
- Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment + 1)); // initialization calls seq twice
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
}
// now force a "clock over"
entities[increment] = new Entity("" + increment);
s.Save(entities[increment]);
Assert.That(generator.TableAccessCount, Is.EqualTo(3)); // initialization (2) + clock over
- Assert.That(optimizer.LastSourceValue, Is.EqualTo((increment * 2) + 1)); // initialization (2) + clock over
- Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo((increment * 2) + 1)); // initialization (2) + clock over
+ Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
transaction.Commit();
}
diff --git a/src/NHibernate.Test/MultiTenancy/TestCaseWithMultiTenancy.cs b/src/NHibernate.Test/MultiTenancy/TestCaseWithMultiTenancy.cs
new file mode 100644
index 00000000000..5ce6ae74477
--- /dev/null
+++ b/src/NHibernate.Test/MultiTenancy/TestCaseWithMultiTenancy.cs
@@ -0,0 +1,60 @@
+using System.Data.Common;
+using NHibernate.Cfg;
+using NHibernate.Dialect;
+using NHibernate.Driver;
+using NHibernate.MultiTenancy;
+
+namespace NHibernate.Test.MultiTenancy
+{
+ public abstract class TestCaseWithMultiTenancy : TestCase
+ {
+ protected TestCaseWithMultiTenancy(string tenantIdentifier)
+ {
+ TenantIdentifier = tenantIdentifier;
+ }
+
+ public string TenantIdentifier { get; }
+
+ protected override void Configure(Configuration configuration)
+ {
+ if (TenantIdentifier != null)
+ {
+ configuration.DataBaseIntegration(
+ x =>
+ {
+ x.MultiTenancy = MultiTenancyStrategy.Database;
+ x.MultiTenancyConnectionProvider();
+ });
+ }
+ base.Configure(configuration);
+ }
+
+ protected override DbConnection OpenConnectionForSchemaExport()
+ {
+ if (TenantIdentifier != null)
+ {
+ return Sfi.Settings.MultiTenancyConnectionProvider
+ .GetConnectionAccess(GetTenantConfig("defaultTenant"), Sfi).GetConnection();
+ }
+ return base.OpenConnectionForSchemaExport();
+ }
+
+ private TenantConfiguration GetTenantConfig(string tenantId)
+ {
+ return new TestTenantConfiguration(tenantId, IsSqlServerDialect);
+ }
+
+ protected override ISession OpenSession()
+ {
+ if (TenantIdentifier != null)
+ {
+ return Sfi.WithOptions().Tenant(new TestTenantConfiguration(TenantIdentifier, IsSqlServerDialect)).OpenSession();
+ }
+ return base.OpenSession();
+ }
+
+ //Create extension method for this?
+ private bool IsSqlServerDialect => Sfi.Dialect is MsSql2000Dialect && !(Sfi.ConnectionProvider.Driver is OdbcDriver);
+
+ }
+}
diff --git a/src/NHibernate.Test/TestCase.cs b/src/NHibernate.Test/TestCase.cs
index 1335b6a722a..5db87e14a72 100644
--- a/src/NHibernate.Test/TestCase.cs
+++ b/src/NHibernate.Test/TestCase.cs
@@ -21,6 +21,8 @@
using NHibernate.SqlTypes;
using NHibernate.Util;
using NSubstitute;
+using NHibernate.MultiTenancy;
+using NHibernate.Test.MultiTenancy;
namespace NHibernate.Test
{
diff --git a/src/NHibernate/Async/Id/Enhanced/IAccessCallback.cs b/src/NHibernate/Async/Id/Enhanced/IAccessCallback.cs
index b52c3e524b5..8fbb5c27826 100644
--- a/src/NHibernate/Async/Id/Enhanced/IAccessCallback.cs
+++ b/src/NHibernate/Async/Id/Enhanced/IAccessCallback.cs
@@ -20,4 +20,4 @@ public partial interface IAccessCallback
/// A cancellation token that can be used to cancel the work
Task GetNextValueAsync(CancellationToken cancellationToken);
}
-}
\ No newline at end of file
+}
diff --git a/src/NHibernate/Async/Id/Enhanced/OptimizerFactory.cs b/src/NHibernate/Async/Id/Enhanced/OptimizerFactory.cs
index 5ba08f4a31e..84f66d725ce 100644
--- a/src/NHibernate/Async/Id/Enhanced/OptimizerFactory.cs
+++ b/src/NHibernate/Async/Id/Enhanced/OptimizerFactory.cs
@@ -9,8 +9,8 @@
using System;
+using System.Collections.Concurrent;
using System.Reflection;
-using System.Runtime.CompilerServices;
using NHibernate.Util;
namespace NHibernate.Id.Enhanced
@@ -30,27 +30,29 @@ public override async Task
///
/// The user may specify a max_lo value to determine how often new hi values are
- /// fetched. If sequences are not avaliable, TableHiLoGenerator might be an
+ /// fetched. If sequences are not available, TableHiLoGenerator might be an
/// alternative.
///
///
@@ -43,11 +44,16 @@ public partial class SequenceHiLoGenerator : SequenceGenerator
public const string MaxLo = "max_lo";
private int maxLo;
- private int lo;
- private long hi;
private System.Type returnClass;
+ private TenantStateStore _stateStore;
private readonly AsyncLock _asyncLock = new AsyncLock();
+ private class GenerationState
+ {
+ public long Lo { get; internal set; }
+ public long Hi { get; internal set; }
+ }
+
#region IConfigurable Members
///
@@ -61,8 +67,8 @@ public override void Configure(IType type, IDictionary parms, Di
{
base.Configure(type, parms, dialect);
maxLo = PropertiesHelper.GetInt32(MaxLo, parms, 9);
- lo = maxLo + 1; // so we "clock over" on the first invocation
returnClass = type.ReturnedClass;
+ _stateStore = new TenantStateStore(state => state.Lo = maxLo + 1);// so we "clock over" on the first invocation
}
#endregion
@@ -80,6 +86,8 @@ public override object Generate(ISessionImplementor session, object obj)
{
using (_asyncLock.Lock())
{
+ var generationState = _stateStore.LocateGenerationState(session.GetTenantIdentifier());
+
if (maxLo < 1)
{
//keep the behavior consistent even for boundary usages
@@ -89,15 +97,15 @@ public override object Generate(ISessionImplementor session, object obj)
return IdentifierGeneratorFactory.CreateNumber(val, returnClass);
}
- if (lo > maxLo)
+ if (generationState.Lo > maxLo)
{
long hival = Convert.ToInt64(base.Generate(session, obj));
- lo = (hival == 0) ? 1 : 0;
- hi = hival * (maxLo + 1);
+ generationState.Lo = (hival == 0) ? 1 : 0;
+ generationState.Hi = hival * (maxLo + 1);
if (log.IsDebugEnabled())
log.Debug("new hi value: {0}", hival);
}
- return IdentifierGeneratorFactory.CreateNumber(hi + lo++, returnClass);
+ return IdentifierGeneratorFactory.CreateNumber(generationState.Hi + generationState.Lo++, returnClass);
}
}
diff --git a/src/NHibernate/Id/TableGenerator.cs b/src/NHibernate/Id/TableGenerator.cs
index 09180687efc..3fbd16e4015 100644
--- a/src/NHibernate/Id/TableGenerator.cs
+++ b/src/NHibernate/Id/TableGenerator.cs
@@ -157,7 +157,7 @@ public virtual object Generate(ISessionImplementor session, object obj)
using (_asyncLock.Lock())
{
// This has to be done using a different connection to the containing
- // transaction becase the new hi value must remain valid even if the
+ // transaction because the new hi value must remain valid even if the
// containing transaction rolls back.
return DoWorkInNewTransaction(session);
}
@@ -220,7 +220,7 @@ public override object DoWorkInCurrentTransaction(ISessionImplementor session, D
int rows;
do
{
- //the loop ensure atomicitiy of the
+ //the loop ensures atomicity of the
//select + update even for no transaction
//or read committed isolation level (needed for .net?)
diff --git a/src/NHibernate/Id/TableHiLoGenerator.cs b/src/NHibernate/Id/TableHiLoGenerator.cs
index c64de1d3323..2ab763bf78e 100644
--- a/src/NHibernate/Id/TableHiLoGenerator.cs
+++ b/src/NHibernate/Id/TableHiLoGenerator.cs
@@ -6,6 +6,7 @@
using NHibernate.Type;
using NHibernate.Util;
using System.Collections.Generic;
+using System.Collections.Concurrent;
namespace NHibernate.Id
{
@@ -48,12 +49,17 @@ public partial class TableHiLoGenerator : TableGenerator
///
public const string MaxLo = "max_lo";
- private long hi;
- private long lo;
private long maxLo;
private System.Type returnClass;
+ private TenantStateStore _stateStore;
private readonly AsyncLock _asyncLock = new AsyncLock();
+ private class GenerationState
+ {
+ public long Lo { get; internal set; }
+ public long Hi { get; internal set; }
+ }
+
#region IConfigurable Members
///
@@ -67,8 +73,8 @@ public override void Configure(IType type, IDictionary parms, Di
{
base.Configure(type, parms, dialect);
maxLo = PropertiesHelper.GetInt64(MaxLo, parms, Int16.MaxValue);
- lo = maxLo + 1; // so we "clock over" on the first invocation
returnClass = type.ReturnedClass;
+ _stateStore = new TenantStateStore(state => state.Lo = maxLo + 1);// so we "clock over" on the first invocation
}
#endregion
@@ -85,6 +91,8 @@ public override object Generate(ISessionImplementor session, object obj)
{
using (_asyncLock.Lock())
{
+ var generationState = _stateStore.LocateGenerationState(session.GetTenantIdentifier());
+
if (maxLo < 1)
{
//keep the behavior consistent even for boundary usages
@@ -93,18 +101,61 @@ public override object Generate(ISessionImplementor session, object obj)
val = Convert.ToInt64(base.Generate(session, obj));
return IdentifierGeneratorFactory.CreateNumber(val, returnClass);
}
- if (lo > maxLo)
+ if (generationState.Lo > maxLo)
{
long hival = Convert.ToInt64(base.Generate(session, obj));
- lo = (hival == 0) ? 1 : 0;
- hi = hival * (maxLo + 1);
+ generationState.Lo = (hival == 0) ? 1 : 0;
+ generationState.Hi = hival * (maxLo + 1);
log.Debug("New high value: {0}", hival);
}
- return IdentifierGeneratorFactory.CreateNumber(hi + lo++, returnClass);
+ return IdentifierGeneratorFactory.CreateNumber(generationState.Hi + generationState.Lo++, returnClass);
}
}
#endregion
}
+
+ internal class TenantStateStore where TState : new()
+ {
+ private TState _noTenantState;
+ private Action _initializer;
+ private readonly Lazy> _tenantSpecificState = new Lazy>(() => new ConcurrentDictionary());
+
+ public TenantStateStore(Action initializer)
+ {
+ _initializer = initializer;
+ }
+
+ public TenantStateStore()
+ {
+ }
+
+ internal TState LocateGenerationState(string tenantIdentifier)
+ {
+ if (tenantIdentifier == null)
+ {
+ if (_noTenantState == null)
+ {
+ _noTenantState = CreateNewState();
+ }
+ return _noTenantState;
+ }
+ else
+ {
+ return _tenantSpecificState.Value.GetOrAdd(tenantIdentifier, _ => CreateNewState());
+ }
+ }
+
+ internal TState NoTenantGenerationState => _noTenantState ??
+ throw new HibernateException("Could not locate previous generation state for no-tenant");
+
+
+ private TState CreateNewState()
+ {
+ var state = new TState();
+ _initializer?.Invoke(state);
+ return state;
+ }
+ }
}
From 553a95153a8697ca5428a8e9bba0313bc76a8566 Mon Sep 17 00:00:00 2001
From: gliljas
Date: Tue, 11 Apr 2023 17:22:49 +0200
Subject: [PATCH 2/5] Split file
---
src/NHibernate/Id/TableHiLoGenerator.cs | 43 ----------------------
src/NHibernate/Id/TenantStateStore.cs | 48 +++++++++++++++++++++++++
2 files changed, 48 insertions(+), 43 deletions(-)
create mode 100644 src/NHibernate/Id/TenantStateStore.cs
diff --git a/src/NHibernate/Id/TableHiLoGenerator.cs b/src/NHibernate/Id/TableHiLoGenerator.cs
index 2ab763bf78e..1629fc7430e 100644
--- a/src/NHibernate/Id/TableHiLoGenerator.cs
+++ b/src/NHibernate/Id/TableHiLoGenerator.cs
@@ -115,47 +115,4 @@ public override object Generate(ISessionImplementor session, object obj)
#endregion
}
-
- internal class TenantStateStore where TState : new()
- {
- private TState _noTenantState;
- private Action _initializer;
- private readonly Lazy> _tenantSpecificState = new Lazy>(() => new ConcurrentDictionary());
-
- public TenantStateStore(Action initializer)
- {
- _initializer = initializer;
- }
-
- public TenantStateStore()
- {
- }
-
- internal TState LocateGenerationState(string tenantIdentifier)
- {
- if (tenantIdentifier == null)
- {
- if (_noTenantState == null)
- {
- _noTenantState = CreateNewState();
- }
- return _noTenantState;
- }
- else
- {
- return _tenantSpecificState.Value.GetOrAdd(tenantIdentifier, _ => CreateNewState());
- }
- }
-
- internal TState NoTenantGenerationState => _noTenantState ??
- throw new HibernateException("Could not locate previous generation state for no-tenant");
-
-
- private TState CreateNewState()
- {
- var state = new TState();
- _initializer?.Invoke(state);
- return state;
- }
- }
}
diff --git a/src/NHibernate/Id/TenantStateStore.cs b/src/NHibernate/Id/TenantStateStore.cs
new file mode 100644
index 00000000000..fbb4d8372a6
--- /dev/null
+++ b/src/NHibernate/Id/TenantStateStore.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Collections.Concurrent;
+
+namespace NHibernate.Id
+{
+ internal class TenantStateStore where TState : new()
+ {
+ private TState _noTenantState;
+ private Action _initializer;
+ private readonly Lazy> _tenantSpecificState = new Lazy>(() => new ConcurrentDictionary());
+
+ public TenantStateStore(Action initializer)
+ {
+ _initializer = initializer;
+ }
+
+ public TenantStateStore()
+ {
+ }
+
+ internal TState LocateGenerationState(string tenantIdentifier)
+ {
+ if (tenantIdentifier == null)
+ {
+ if (_noTenantState == null)
+ {
+ _noTenantState = CreateNewState();
+ }
+ return _noTenantState;
+ }
+ else
+ {
+ return _tenantSpecificState.Value.GetOrAdd(tenantIdentifier, _ => CreateNewState());
+ }
+ }
+
+ internal TState NoTenantGenerationState => _noTenantState ??
+ throw new HibernateException("Could not locate previous generation state for no-tenant");
+
+
+ private TState CreateNewState()
+ {
+ var state = new TState();
+ _initializer?.Invoke(state);
+ return state;
+ }
+ }
+}
From dfa4734eaa6a2550784262d04eb41ed1d339162b Mon Sep 17 00:00:00 2001
From: gliljas
Date: Tue, 11 Apr 2023 18:36:48 +0200
Subject: [PATCH 3/5] Fix for #3229
---
src/NHibernate/Id/Enhanced/OptimizerFactory.cs | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/NHibernate/Id/Enhanced/OptimizerFactory.cs b/src/NHibernate/Id/Enhanced/OptimizerFactory.cs
index c54c53fbafe..d599ce49521 100644
--- a/src/NHibernate/Id/Enhanced/OptimizerFactory.cs
+++ b/src/NHibernate/Id/Enhanced/OptimizerFactory.cs
@@ -412,8 +412,10 @@ public override object Generate(IAccessCallback callback)
generationState.LastSourceValue = callback.GetNextValue();
generationState.Value = generationState.LastSourceValue;
// handle cases where initial-value is less than one (hsqldb for instance).
- while (generationState.Value < 1)
- generationState.Value++;
+ if (generationState.Value < 1)
+ {
+ generationState.Value = 1;
+ }
}
return Make(generationState.Value++);
From e63dca4599cecbaebb5ac94d3a46c842f7eb7788 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
Date: Tue, 11 Apr 2023 16:40:25 +0000
Subject: [PATCH 4/5] Generate async files
---
src/NHibernate/Async/Id/Enhanced/OptimizerFactory.cs | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/NHibernate/Async/Id/Enhanced/OptimizerFactory.cs b/src/NHibernate/Async/Id/Enhanced/OptimizerFactory.cs
index 84f66d725ce..f18744e6c08 100644
--- a/src/NHibernate/Async/Id/Enhanced/OptimizerFactory.cs
+++ b/src/NHibernate/Async/Id/Enhanced/OptimizerFactory.cs
@@ -159,8 +159,10 @@ public override async Task GenerateAsync(IAccessCallback callback, Cance
generationState.LastSourceValue = await (callback.GetNextValueAsync(cancellationToken)).ConfigureAwait(false);
generationState.Value = generationState.LastSourceValue;
// handle cases where initial-value is less than one (hsqldb for instance).
- while (generationState.Value < 1)
- generationState.Value++;
+ if (generationState.Value < 1)
+ {
+ generationState.Value = 1;
+ }
}
return Make(generationState.Value++);
From ff20724fe3b5d23187e5ff86b7565d8bd8817fb4 Mon Sep 17 00:00:00 2001
From: gliljas
Date: Wed, 12 Apr 2023 17:30:52 +0200
Subject: [PATCH 5/5] Corrections in review
---
.../HiLoForcedTableSequenceTest.cs | 12 ++++++++
.../PooledForcedTableSequenceTest.cs | 13 +++++++-
.../Enhanced/Sequence/HiLoSequenceTest.cs | 12 ++++++++
.../Enhanced/Sequence/PooledSequenceTest.cs | 10 +++++++
.../IdGen/Enhanced/Table/HiLoTableTest.cs | 12 ++++++++
.../IdGen/Enhanced/Table/PooledLoTableTest.cs | 10 +++++++
.../IdGen/Enhanced/Table/PooledTableTest.cs | 10 +++++++
.../HiLoForcedTableSequenceTest.cs | 12 ++++++++
.../PooledForcedTableSequenceTest.cs | 13 +++++++-
.../Enhanced/Sequence/HiLoSequenceTest.cs | 12 ++++++++
.../Enhanced/Sequence/PooledSequenceTest.cs | 10 +++++++
.../IdGen/Enhanced/Table/HiLoTableTest.cs | 12 ++++++++
.../IdGen/Enhanced/Table/PooledLoTableTest.cs | 10 +++++++
.../IdGen/Enhanced/Table/PooledTableTest.cs | 10 +++++++
.../Async/Id/Enhanced/OptimizerFactory.cs | 22 +++++++-------
.../Async/Id/SequenceHiLoGenerator.cs | 7 +++--
src/NHibernate/Async/Id/TableHiLoGenerator.cs | 7 +++--
.../Id/Enhanced/OptimizerFactory.cs | 30 +++++++++++--------
src/NHibernate/Id/SequenceHiLoGenerator.cs | 10 +++----
src/NHibernate/Id/TableHiLoGenerator.cs | 10 +++----
src/NHibernate/Id/TenantStateStore.cs | 18 +++++------
21 files changed, 211 insertions(+), 51 deletions(-)
diff --git a/src/NHibernate.Test/Async/IdGen/Enhanced/Forcedtable/HiLoForcedTableSequenceTest.cs b/src/NHibernate.Test/Async/IdGen/Enhanced/Forcedtable/HiLoForcedTableSequenceTest.cs
index abf9104e83f..0cff9650e6a 100644
--- a/src/NHibernate.Test/Async/IdGen/Enhanced/Forcedtable/HiLoForcedTableSequenceTest.cs
+++ b/src/NHibernate.Test/Async/IdGen/Enhanced/Forcedtable/HiLoForcedTableSequenceTest.cs
@@ -58,6 +58,12 @@ public async Task TestNormalBoundaryAsync()
long expectedId = i + 1;
Assert.That(entities[i].Id, Is.EqualTo(expectedId));
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(1)); // initialization
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(1)); // initialization
+ Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
+ Assert.That(optimizer.HiValue, Is.EqualTo(increment + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(1)); // initialization
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo(increment + 1));
@@ -68,6 +74,12 @@ public async Task TestNormalBoundaryAsync()
await (session.SaveAsync(entities[increment]));
Assert.That(entities[optimizer.IncrementSize].Id, Is.EqualTo(optimizer.IncrementSize + 1));
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(2)); // initialization + clock-over
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(2)); // initialization + clock-over
+ Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
+ Assert.That(optimizer.HiValue, Is.EqualTo(increment * 2 + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(2)); // initialization + clock-over
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo(increment * 2 + 1));
diff --git a/src/NHibernate.Test/Async/IdGen/Enhanced/Forcedtable/PooledForcedTableSequenceTest.cs b/src/NHibernate.Test/Async/IdGen/Enhanced/Forcedtable/PooledForcedTableSequenceTest.cs
index 9f5f3a4168a..03924789aaa 100644
--- a/src/NHibernate.Test/Async/IdGen/Enhanced/Forcedtable/PooledForcedTableSequenceTest.cs
+++ b/src/NHibernate.Test/Async/IdGen/Enhanced/Forcedtable/PooledForcedTableSequenceTest.cs
@@ -59,6 +59,11 @@ public async Task TestNormalBoundaryAsync()
Assert.That(entities[i].Id, Is.EqualTo(expectedId));
// NOTE : initialization calls table twice
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(2)); // initialization
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment + 1)); // initialization
+ Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment + 1)); // initialization
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
}
@@ -70,9 +75,15 @@ public async Task TestNormalBoundaryAsync()
Assert.That(entities[optimizer.IncrementSize].Id, Is.EqualTo(optimizer.IncrementSize + 1));
// initialization (2) + clock over
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(3));
- Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment*2 + 1));
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment * 2 + 1));
+ Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
+ }
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment * 2 + 1));
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
+
await (transaction.CommitAsync());
}
diff --git a/src/NHibernate.Test/Async/IdGen/Enhanced/Sequence/HiLoSequenceTest.cs b/src/NHibernate.Test/Async/IdGen/Enhanced/Sequence/HiLoSequenceTest.cs
index 4b1606cf330..9942b263e6a 100644
--- a/src/NHibernate.Test/Async/IdGen/Enhanced/Sequence/HiLoSequenceTest.cs
+++ b/src/NHibernate.Test/Async/IdGen/Enhanced/Sequence/HiLoSequenceTest.cs
@@ -56,6 +56,12 @@ public async Task TestNormalBoundaryAsync()
entities[i] = new Entity("" + (i + 1));
await (session.SaveAsync(entities[i]));
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(1)); // initialization
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(1)); // initialization
+ Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
+ Assert.That(optimizer.HiValue, Is.EqualTo(increment + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(1)); // initialization
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo(increment + 1));
@@ -65,6 +71,12 @@ public async Task TestNormalBoundaryAsync()
entities[increment] = new Entity("" + increment);
await (session.SaveAsync(entities[increment]));
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(2));
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(2));
+ Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
+ Assert.That(optimizer.HiValue, Is.EqualTo(increment * 2 + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(2));
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo(increment * 2 + 1));
diff --git a/src/NHibernate.Test/Async/IdGen/Enhanced/Sequence/PooledSequenceTest.cs b/src/NHibernate.Test/Async/IdGen/Enhanced/Sequence/PooledSequenceTest.cs
index 1d06ae11d89..47c2ca1a82d 100644
--- a/src/NHibernate.Test/Async/IdGen/Enhanced/Sequence/PooledSequenceTest.cs
+++ b/src/NHibernate.Test/Async/IdGen/Enhanced/Sequence/PooledSequenceTest.cs
@@ -55,6 +55,11 @@ public async Task TestNormalBoundaryAsync()
entities[i] = new Entity("" + (i + 1));
await (session.SaveAsync(entities[i]));
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(2)); // initialization calls seq twice
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment + 1)); // initialization calls seq twice
+ Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment + 1)); // initialization calls seq twice
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
}
@@ -63,6 +68,11 @@ public async Task TestNormalBoundaryAsync()
entities[increment] = new Entity("" + increment);
await (session.SaveAsync(entities[increment]));
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(3)); // initialization (2) + clock over
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment * 2 + 1)); // initialization (2) + clock over
+ Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment * 2 + 1)); // initialization (2) + clock over
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
diff --git a/src/NHibernate.Test/Async/IdGen/Enhanced/Table/HiLoTableTest.cs b/src/NHibernate.Test/Async/IdGen/Enhanced/Table/HiLoTableTest.cs
index 2e53c916aea..9938d691506 100644
--- a/src/NHibernate.Test/Async/IdGen/Enhanced/Table/HiLoTableTest.cs
+++ b/src/NHibernate.Test/Async/IdGen/Enhanced/Table/HiLoTableTest.cs
@@ -55,6 +55,12 @@ public async Task TestNormalBoundaryAsync()
entities[i] = new Entity("" + (i + 1));
await (s.SaveAsync(entities[i]));
Assert.That(generator.TableAccessCount, Is.EqualTo(1)); // initialization
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(1)); // initialization
+ Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
+ Assert.That(optimizer.HiValue, Is.EqualTo(increment + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(1)); // initialization
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo(increment + 1));
@@ -64,6 +70,12 @@ public async Task TestNormalBoundaryAsync()
entities[increment] = new Entity("" + increment);
await (s.SaveAsync(entities[increment]));
Assert.That(generator.TableAccessCount, Is.EqualTo(2));
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(2));
+ Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
+ Assert.That(optimizer.HiValue, Is.EqualTo((increment * 2) + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(2));
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo((increment * 2) + 1));
diff --git a/src/NHibernate.Test/Async/IdGen/Enhanced/Table/PooledLoTableTest.cs b/src/NHibernate.Test/Async/IdGen/Enhanced/Table/PooledLoTableTest.cs
index af309699513..a5afc87bb50 100644
--- a/src/NHibernate.Test/Async/IdGen/Enhanced/Table/PooledLoTableTest.cs
+++ b/src/NHibernate.Test/Async/IdGen/Enhanced/Table/PooledLoTableTest.cs
@@ -55,6 +55,11 @@ public async Task TestNormalBoundaryAsync()
entities[i] = new Entity("" + (i + 1));
await (s.SaveAsync(entities[i]));
Assert.That(generator.TableAccessCount, Is.EqualTo(1)); // initialization
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(1)); // initialization
+ Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(1)); // initialization
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
}
@@ -63,6 +68,11 @@ public async Task TestNormalBoundaryAsync()
entities[increment] = new Entity("" + increment);
await (s.SaveAsync(entities[increment]));
Assert.That(generator.TableAccessCount, Is.EqualTo(2));
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment + 1));
+ Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment + 1));
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
diff --git a/src/NHibernate.Test/Async/IdGen/Enhanced/Table/PooledTableTest.cs b/src/NHibernate.Test/Async/IdGen/Enhanced/Table/PooledTableTest.cs
index 15be48dccaa..439de62e4cd 100644
--- a/src/NHibernate.Test/Async/IdGen/Enhanced/Table/PooledTableTest.cs
+++ b/src/NHibernate.Test/Async/IdGen/Enhanced/Table/PooledTableTest.cs
@@ -54,6 +54,11 @@ public async Task TestNormalBoundaryAsync()
entities[i] = new Entity("" + (i + 1));
await (s.SaveAsync(entities[i]));
Assert.That(generator.TableAccessCount, Is.EqualTo(2)); // initialization calls seq twice
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment + 1)); // initialization calls seq twice
+ Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment + 1)); // initialization calls seq twice
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
}
@@ -62,6 +67,11 @@ public async Task TestNormalBoundaryAsync()
entities[increment] = new Entity("" + increment);
await (s.SaveAsync(entities[increment]));
Assert.That(generator.TableAccessCount, Is.EqualTo(3)); // initialization (2) + clock over
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo((increment * 2) + 1)); // initialization (2) + clock over
+ Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo((increment * 2) + 1)); // initialization (2) + clock over
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
diff --git a/src/NHibernate.Test/IdGen/Enhanced/Forcedtable/HiLoForcedTableSequenceTest.cs b/src/NHibernate.Test/IdGen/Enhanced/Forcedtable/HiLoForcedTableSequenceTest.cs
index e8647f3858f..2411dfada16 100644
--- a/src/NHibernate.Test/IdGen/Enhanced/Forcedtable/HiLoForcedTableSequenceTest.cs
+++ b/src/NHibernate.Test/IdGen/Enhanced/Forcedtable/HiLoForcedTableSequenceTest.cs
@@ -47,6 +47,12 @@ public void TestNormalBoundary()
long expectedId = i + 1;
Assert.That(entities[i].Id, Is.EqualTo(expectedId));
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(1)); // initialization
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(1)); // initialization
+ Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
+ Assert.That(optimizer.HiValue, Is.EqualTo(increment + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(1)); // initialization
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo(increment + 1));
@@ -57,6 +63,12 @@ public void TestNormalBoundary()
session.Save(entities[increment]);
Assert.That(entities[optimizer.IncrementSize].Id, Is.EqualTo(optimizer.IncrementSize + 1));
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(2)); // initialization + clock-over
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(2)); // initialization + clock-over
+ Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
+ Assert.That(optimizer.HiValue, Is.EqualTo(increment * 2 + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(2)); // initialization + clock-over
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo(increment * 2 + 1));
diff --git a/src/NHibernate.Test/IdGen/Enhanced/Forcedtable/PooledForcedTableSequenceTest.cs b/src/NHibernate.Test/IdGen/Enhanced/Forcedtable/PooledForcedTableSequenceTest.cs
index 39598c9d591..4add7229bba 100644
--- a/src/NHibernate.Test/IdGen/Enhanced/Forcedtable/PooledForcedTableSequenceTest.cs
+++ b/src/NHibernate.Test/IdGen/Enhanced/Forcedtable/PooledForcedTableSequenceTest.cs
@@ -48,6 +48,11 @@ public void TestNormalBoundary()
Assert.That(entities[i].Id, Is.EqualTo(expectedId));
// NOTE : initialization calls table twice
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(2)); // initialization
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment + 1)); // initialization
+ Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment + 1)); // initialization
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
}
@@ -59,9 +64,15 @@ public void TestNormalBoundary()
Assert.That(entities[optimizer.IncrementSize].Id, Is.EqualTo(optimizer.IncrementSize + 1));
// initialization (2) + clock over
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(3));
- Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment*2 + 1));
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment * 2 + 1));
+ Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
+ }
+ Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment * 2 + 1));
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
+
transaction.Commit();
}
diff --git a/src/NHibernate.Test/IdGen/Enhanced/Sequence/HiLoSequenceTest.cs b/src/NHibernate.Test/IdGen/Enhanced/Sequence/HiLoSequenceTest.cs
index 7cd6161bc02..10db766ed8b 100644
--- a/src/NHibernate.Test/IdGen/Enhanced/Sequence/HiLoSequenceTest.cs
+++ b/src/NHibernate.Test/IdGen/Enhanced/Sequence/HiLoSequenceTest.cs
@@ -45,6 +45,12 @@ public void TestNormalBoundary()
entities[i] = new Entity("" + (i + 1));
session.Save(entities[i]);
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(1)); // initialization
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(1)); // initialization
+ Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
+ Assert.That(optimizer.HiValue, Is.EqualTo(increment + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(1)); // initialization
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo(increment + 1));
@@ -54,6 +60,12 @@ public void TestNormalBoundary()
entities[increment] = new Entity("" + increment);
session.Save(entities[increment]);
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(2));
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(2));
+ Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
+ Assert.That(optimizer.HiValue, Is.EqualTo(increment * 2 + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(2));
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo(increment * 2 + 1));
diff --git a/src/NHibernate.Test/IdGen/Enhanced/Sequence/PooledSequenceTest.cs b/src/NHibernate.Test/IdGen/Enhanced/Sequence/PooledSequenceTest.cs
index b18c211b7ba..669c03376db 100644
--- a/src/NHibernate.Test/IdGen/Enhanced/Sequence/PooledSequenceTest.cs
+++ b/src/NHibernate.Test/IdGen/Enhanced/Sequence/PooledSequenceTest.cs
@@ -44,6 +44,11 @@ public void TestNormalBoundary()
entities[i] = new Entity("" + (i + 1));
session.Save(entities[i]);
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(2)); // initialization calls seq twice
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment + 1)); // initialization calls seq twice
+ Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment + 1)); // initialization calls seq twice
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
}
@@ -52,6 +57,11 @@ public void TestNormalBoundary()
entities[increment] = new Entity("" + increment);
session.Save(entities[increment]);
Assert.That(generator.DatabaseStructure.TimesAccessed, Is.EqualTo(3)); // initialization (2) + clock over
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment * 2 + 1)); // initialization (2) + clock over
+ Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment * 2 + 1)); // initialization (2) + clock over
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
diff --git a/src/NHibernate.Test/IdGen/Enhanced/Table/HiLoTableTest.cs b/src/NHibernate.Test/IdGen/Enhanced/Table/HiLoTableTest.cs
index 014788d6570..d25c772661c 100644
--- a/src/NHibernate.Test/IdGen/Enhanced/Table/HiLoTableTest.cs
+++ b/src/NHibernate.Test/IdGen/Enhanced/Table/HiLoTableTest.cs
@@ -44,6 +44,12 @@ public void TestNormalBoundary()
entities[i] = new Entity("" + (i + 1));
s.Save(entities[i]);
Assert.That(generator.TableAccessCount, Is.EqualTo(1)); // initialization
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(1)); // initialization
+ Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
+ Assert.That(optimizer.HiValue, Is.EqualTo(increment + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(1)); // initialization
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo(increment + 1));
@@ -53,6 +59,12 @@ public void TestNormalBoundary()
entities[increment] = new Entity("" + increment);
s.Save(entities[increment]);
Assert.That(generator.TableAccessCount, Is.EqualTo(2));
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(2));
+ Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
+ Assert.That(optimizer.HiValue, Is.EqualTo((increment * 2) + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(2));
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
Assert.That(optimizer.GetHiValue(TenantIdentifier), Is.EqualTo((increment * 2) + 1));
diff --git a/src/NHibernate.Test/IdGen/Enhanced/Table/PooledLoTableTest.cs b/src/NHibernate.Test/IdGen/Enhanced/Table/PooledLoTableTest.cs
index e56c2fed120..4181a25372e 100644
--- a/src/NHibernate.Test/IdGen/Enhanced/Table/PooledLoTableTest.cs
+++ b/src/NHibernate.Test/IdGen/Enhanced/Table/PooledLoTableTest.cs
@@ -44,6 +44,11 @@ public void TestNormalBoundary()
entities[i] = new Entity("" + (i + 1));
s.Save(entities[i]);
Assert.That(generator.TableAccessCount, Is.EqualTo(1)); // initialization
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(1)); // initialization
+ Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(1)); // initialization
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
}
@@ -52,6 +57,11 @@ public void TestNormalBoundary()
entities[increment] = new Entity("" + increment);
s.Save(entities[increment]);
Assert.That(generator.TableAccessCount, Is.EqualTo(2));
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment + 1));
+ Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment + 1));
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
diff --git a/src/NHibernate.Test/IdGen/Enhanced/Table/PooledTableTest.cs b/src/NHibernate.Test/IdGen/Enhanced/Table/PooledTableTest.cs
index 4f357bc6066..383b2925b03 100644
--- a/src/NHibernate.Test/IdGen/Enhanced/Table/PooledTableTest.cs
+++ b/src/NHibernate.Test/IdGen/Enhanced/Table/PooledTableTest.cs
@@ -43,6 +43,11 @@ public void TestNormalBoundary()
entities[i] = new Entity("" + (i + 1));
s.Save(entities[i]);
Assert.That(generator.TableAccessCount, Is.EqualTo(2)); // initialization calls seq twice
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo(increment + 1)); // initialization calls seq twice
+ Assert.That(optimizer.LastValue, Is.EqualTo(i + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo(increment + 1)); // initialization calls seq twice
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(i + 1));
}
@@ -51,6 +56,11 @@ public void TestNormalBoundary()
entities[increment] = new Entity("" + increment);
s.Save(entities[increment]);
Assert.That(generator.TableAccessCount, Is.EqualTo(3)); // initialization (2) + clock over
+ if (TenantIdentifier == null)
+ {
+ Assert.That(optimizer.LastSourceValue, Is.EqualTo((increment * 2) + 1)); // initialization (2) + clock over
+ Assert.That(optimizer.LastValue, Is.EqualTo(increment + 1));
+ }
Assert.That(optimizer.GetLastSourceValue(TenantIdentifier), Is.EqualTo((increment * 2) + 1)); // initialization (2) + clock over
Assert.That(optimizer.GetLastValue(TenantIdentifier), Is.EqualTo(increment + 1));
diff --git a/src/NHibernate/Async/Id/Enhanced/OptimizerFactory.cs b/src/NHibernate/Async/Id/Enhanced/OptimizerFactory.cs
index f18744e6c08..1e9350f3e94 100644
--- a/src/NHibernate/Async/Id/Enhanced/OptimizerFactory.cs
+++ b/src/NHibernate/Async/Id/Enhanced/OptimizerFactory.cs
@@ -9,7 +9,6 @@
using System;
-using System.Collections.Concurrent;
using System.Reflection;
using NHibernate.Util;
@@ -28,10 +27,11 @@ public partial class HiLoOptimizer : OptimizerSupport
public override async Task GenerateAsync(IAccessCallback callback, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
- using (await (_asyncLock.LockAsync()).ConfigureAwait(false))
- {
- var generationState = _stateStore.LocateGenerationState(callback.GetTenantIdentifier());
+ var generationState = _stateStore.LocateGenerationState(callback.GetTenantIdentifier());
+ cancellationToken.ThrowIfCancellationRequested();
+ using (await (generationState.AsyncLock.LockAsync()).ConfigureAwait(false))
+ {
if (generationState.LastSourceValue < 0)
{
generationState.LastSourceValue = await (callback.GetNextValueAsync(cancellationToken)).ConfigureAwait(false);
@@ -106,10 +106,11 @@ public partial class PooledOptimizer : OptimizerSupport, IInitialValueAwareOptim
public override async Task GenerateAsync(IAccessCallback callback, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
- using (await (_asyncLock.LockAsync()).ConfigureAwait(false))
- {
- var generationState = _stateStore.LocateGenerationState(callback.GetTenantIdentifier());
+ var generationState = _stateStore.LocateGenerationState(callback.GetTenantIdentifier());
+ cancellationToken.ThrowIfCancellationRequested();
+ using (await (generationState.AsyncLock.LockAsync()).ConfigureAwait(false))
+ {
if (generationState.HiValue < 0)
{
generationState.Value = await (callback.GetNextValueAsync(cancellationToken)).ConfigureAwait(false);
@@ -150,10 +151,11 @@ public partial class PooledLoOptimizer : OptimizerSupport
public override async Task GenerateAsync(IAccessCallback callback, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
- using (await (_asyncLock.LockAsync()).ConfigureAwait(false))
- {
- var generationState = _stateStore.LocateGenerationState(callback.GetTenantIdentifier());
+ var generationState = _stateStore.LocateGenerationState(callback.GetTenantIdentifier());
+ cancellationToken.ThrowIfCancellationRequested();
+ using (await (generationState.AsyncLock.LockAsync()).ConfigureAwait(false))
+ {
if (generationState.LastSourceValue < 0 || generationState.Value >= (generationState.LastSourceValue + IncrementSize))
{
generationState.LastSourceValue = await (callback.GetNextValueAsync(cancellationToken)).ConfigureAwait(false);
diff --git a/src/NHibernate/Async/Id/SequenceHiLoGenerator.cs b/src/NHibernate/Async/Id/SequenceHiLoGenerator.cs
index 7ed2b4a2ef4..ddf62bb98f6 100644
--- a/src/NHibernate/Async/Id/SequenceHiLoGenerator.cs
+++ b/src/NHibernate/Async/Id/SequenceHiLoGenerator.cs
@@ -38,10 +38,11 @@ public partial class SequenceHiLoGenerator : SequenceGenerator
public override async Task GenerateAsync(ISessionImplementor session, object obj, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
- using (await (_asyncLock.LockAsync()).ConfigureAwait(false))
- {
- var generationState = _stateStore.LocateGenerationState(session.GetTenantIdentifier());
+ var generationState = _stateStore.LocateGenerationState(session.GetTenantIdentifier());
+ cancellationToken.ThrowIfCancellationRequested();
+ using (await (generationState.AsyncLock.LockAsync()).ConfigureAwait(false))
+ {
if (maxLo < 1)
{
//keep the behavior consistent even for boundary usages
diff --git a/src/NHibernate/Async/Id/TableHiLoGenerator.cs b/src/NHibernate/Async/Id/TableHiLoGenerator.cs
index 760556da853..8ee8ab67c50 100644
--- a/src/NHibernate/Async/Id/TableHiLoGenerator.cs
+++ b/src/NHibernate/Async/Id/TableHiLoGenerator.cs
@@ -37,10 +37,11 @@ public partial class TableHiLoGenerator : TableGenerator
public override async Task GenerateAsync(ISessionImplementor session, object obj, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
- using (await (_asyncLock.LockAsync()).ConfigureAwait(false))
- {
- var generationState = _stateStore.LocateGenerationState(session.GetTenantIdentifier());
+ var generationState = _stateStore.LocateGenerationState(session.GetTenantIdentifier());
+ cancellationToken.ThrowIfCancellationRequested();
+ using (await (generationState.AsyncLock.LockAsync()).ConfigureAwait(false))
+ {
if (maxLo < 1)
{
//keep the behavior consistent even for boundary usages
diff --git a/src/NHibernate/Id/Enhanced/OptimizerFactory.cs b/src/NHibernate/Id/Enhanced/OptimizerFactory.cs
index d599ce49521..fc239a27145 100644
--- a/src/NHibernate/Id/Enhanced/OptimizerFactory.cs
+++ b/src/NHibernate/Id/Enhanced/OptimizerFactory.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Concurrent;
using System.Reflection;
using NHibernate.Util;
@@ -98,7 +97,6 @@ public static IOptimizer BuildOptimizer(string type, System.Type returnClass, in
public partial class HiLoOptimizer : OptimizerSupport
{
- private readonly AsyncLock _asyncLock = new AsyncLock();
private readonly TenantStateStore _stateStore = new TenantStateStore();
public HiLoOptimizer(System.Type returnClass, int incrementSize) : base(returnClass, incrementSize)
@@ -115,6 +113,7 @@ public HiLoOptimizer(System.Type returnClass, int incrementSize) : base(returnCl
public class GenerationState
{
+ public AsyncLock AsyncLock { get; } = new AsyncLock();
public long LastSourceValue { get; internal set; } = -1;
public long Value { get; internal set; }
public long UpperLimit { get; internal set; }
@@ -162,10 +161,10 @@ public override bool ApplyIncrementSizeToSourceValues
public override object Generate(IAccessCallback callback)
{
- using (_asyncLock.Lock())
- {
- var generationState = _stateStore.LocateGenerationState(callback.GetTenantIdentifier());
+ var generationState = _stateStore.LocateGenerationState(callback.GetTenantIdentifier());
+ using (generationState.AsyncLock.Lock())
+ {
if (generationState.LastSourceValue < 0)
{
generationState.LastSourceValue = callback.GetNextValue();
@@ -290,7 +289,6 @@ protected virtual object Make(long value)
public partial class PooledOptimizer : OptimizerSupport, IInitialValueAwareOptimizer
{
private long _initialValue;
- private readonly AsyncLock _asyncLock = new AsyncLock();
private readonly TenantStateStore _stateStore = new TenantStateStore();
public PooledOptimizer(System.Type returnClass, int incrementSize) : base(returnClass, incrementSize)
{
@@ -306,6 +304,7 @@ public PooledOptimizer(System.Type returnClass, int incrementSize) : base(return
public class GenerationState
{
+ public AsyncLock AsyncLock { get; } = new AsyncLock();
public long Value { get; internal set; }
public long HiValue { get; internal set; } = -1;
}
@@ -319,6 +318,11 @@ public override long LastSourceValue
/// Exposure intended for testing purposes.
///
///
+
+ public long LastValue
+ {
+ get { return _stateStore.NoTenantGenerationState.Value - 1; }
+ }
public long GetLastSourceValue(string tenantIdentifier)
{
return _stateStore.LocateGenerationState(tenantIdentifier).HiValue;
@@ -340,10 +344,10 @@ public void InjectInitialValue(long initialValue)
public override object Generate(IAccessCallback callback)
{
- using (_asyncLock.Lock())
- {
- var generationState = _stateStore.LocateGenerationState(callback.GetTenantIdentifier());
+ var generationState = _stateStore.LocateGenerationState(callback.GetTenantIdentifier());
+ using (generationState.AsyncLock.Lock())
+ {
if (generationState.HiValue < 0)
{
generationState.Value = callback.GetNextValue();
@@ -380,7 +384,6 @@ public override object Generate(IAccessCallback callback)
public partial class PooledLoOptimizer : OptimizerSupport
{
- private readonly AsyncLock _asyncLock = new AsyncLock();
private readonly TenantStateStore _stateStore = new TenantStateStore();
public PooledLoOptimizer(System.Type returnClass, int incrementSize) : base(returnClass, incrementSize)
@@ -397,16 +400,17 @@ public PooledLoOptimizer(System.Type returnClass, int incrementSize) : base(retu
public class GenerationState
{
+ public AsyncLock AsyncLock { get; } = new AsyncLock();
public long LastSourceValue { get; internal set; } = -1;
public long Value { get; internal set; }
}
public override object Generate(IAccessCallback callback)
{
- using (_asyncLock.Lock())
- {
- var generationState = _stateStore.LocateGenerationState(callback.GetTenantIdentifier());
+ var generationState = _stateStore.LocateGenerationState(callback.GetTenantIdentifier());
+ using (generationState.AsyncLock.Lock())
+ {
if (generationState.LastSourceValue < 0 || generationState.Value >= (generationState.LastSourceValue + IncrementSize))
{
generationState.LastSourceValue = callback.GetNextValue();
diff --git a/src/NHibernate/Id/SequenceHiLoGenerator.cs b/src/NHibernate/Id/SequenceHiLoGenerator.cs
index 475027dde93..ec20886f66f 100644
--- a/src/NHibernate/Id/SequenceHiLoGenerator.cs
+++ b/src/NHibernate/Id/SequenceHiLoGenerator.cs
@@ -46,10 +46,10 @@ public partial class SequenceHiLoGenerator : SequenceGenerator
private int maxLo;
private System.Type returnClass;
private TenantStateStore _stateStore;
- private readonly AsyncLock _asyncLock = new AsyncLock();
-
+
private class GenerationState
{
+ public AsyncLock AsyncLock { get; } = new AsyncLock();
public long Lo { get; internal set; }
public long Hi { get; internal set; }
}
@@ -84,10 +84,10 @@ public override void Configure(IType type, IDictionary parms, Di
/// The new identifier as a , , or .
public override object Generate(ISessionImplementor session, object obj)
{
- using (_asyncLock.Lock())
- {
- var generationState = _stateStore.LocateGenerationState(session.GetTenantIdentifier());
+ var generationState = _stateStore.LocateGenerationState(session.GetTenantIdentifier());
+ using (generationState.AsyncLock.Lock())
+ {
if (maxLo < 1)
{
//keep the behavior consistent even for boundary usages
diff --git a/src/NHibernate/Id/TableHiLoGenerator.cs b/src/NHibernate/Id/TableHiLoGenerator.cs
index 1629fc7430e..9cf03db31ac 100644
--- a/src/NHibernate/Id/TableHiLoGenerator.cs
+++ b/src/NHibernate/Id/TableHiLoGenerator.cs
@@ -52,10 +52,10 @@ public partial class TableHiLoGenerator : TableGenerator
private long maxLo;
private System.Type returnClass;
private TenantStateStore _stateStore;
- private readonly AsyncLock _asyncLock = new AsyncLock();
-
+
private class GenerationState
{
+ public AsyncLock AsyncLock { get; } = new AsyncLock();
public long Lo { get; internal set; }
public long Hi { get; internal set; }
}
@@ -89,10 +89,10 @@ public override void Configure(IType type, IDictionary parms, Di
/// The new identifier as a .
public override object Generate(ISessionImplementor session, object obj)
{
- using (_asyncLock.Lock())
- {
- var generationState = _stateStore.LocateGenerationState(session.GetTenantIdentifier());
+ var generationState = _stateStore.LocateGenerationState(session.GetTenantIdentifier());
+ using (generationState.AsyncLock.Lock())
+ {
if (maxLo < 1)
{
//keep the behavior consistent even for boundary usages
diff --git a/src/NHibernate/Id/TenantStateStore.cs b/src/NHibernate/Id/TenantStateStore.cs
index fbb4d8372a6..276df6a3e81 100644
--- a/src/NHibernate/Id/TenantStateStore.cs
+++ b/src/NHibernate/Id/TenantStateStore.cs
@@ -5,36 +5,34 @@ namespace NHibernate.Id
{
internal class TenantStateStore where TState : new()
{
- private TState _noTenantState;
+ private Lazy _noTenantState;
private Action _initializer;
- private readonly Lazy> _tenantSpecificState = new Lazy>(() => new ConcurrentDictionary());
+ private ConcurrentDictionary _tenantSpecificState = new ConcurrentDictionary();
- public TenantStateStore(Action initializer)
+ public TenantStateStore(Action initializer) : this()
{
_initializer = initializer;
}
public TenantStateStore()
{
+ _noTenantState = new Lazy(() => CreateNewState());
}
internal TState LocateGenerationState(string tenantIdentifier)
{
if (tenantIdentifier == null)
{
- if (_noTenantState == null)
- {
- _noTenantState = CreateNewState();
- }
- return _noTenantState;
+ return _noTenantState.Value;
}
else
{
- return _tenantSpecificState.Value.GetOrAdd(tenantIdentifier, _ => CreateNewState());
+ return _tenantSpecificState.GetOrAdd(tenantIdentifier, _ => CreateNewState());
}
}
- internal TState NoTenantGenerationState => _noTenantState ??
+ internal TState NoTenantGenerationState => _noTenantState.IsValueCreated ?
+ _noTenantState.Value :
throw new HibernateException("Could not locate previous generation state for no-tenant");