Skip to content

Commit 03500af

Browse files
Add a shortcut to reduce Transaction.Current reads (nhibernate#2213)
1 parent 1c779fa commit 03500af

File tree

4 files changed

+50
-7
lines changed

4 files changed

+50
-7
lines changed

src/NHibernate.Test/Async/SystemTransactions/SystemTransactionFixture.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,16 @@
1010

1111
using System;
1212
using System.Collections.Generic;
13+
using System.Diagnostics;
1314
using System.Linq;
1415
using System.Threading;
1516
using System.Transactions;
1617
using NHibernate.Cfg;
1718
using NHibernate.Driver;
1819
using NHibernate.Engine;
19-
using NHibernate.Linq;
2020
using NHibernate.Test.TransactionTest;
2121
using NUnit.Framework;
22+
using NHibernate.Linq;
2223

2324
namespace NHibernate.Test.SystemTransactions
2425
{

src/NHibernate.Test/SystemTransactions/SystemTransactionFixture.cs

+39-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Diagnostics;
34
using System.Linq;
45
using System.Threading;
56
using System.Transactions;
67
using NHibernate.Cfg;
78
using NHibernate.Driver;
89
using NHibernate.Engine;
9-
using NHibernate.Linq;
1010
using NHibernate.Test.TransactionTest;
1111
using NUnit.Framework;
1212

@@ -522,6 +522,44 @@ public void AdditionalJoinDoesNotThrow()
522522
Assert.DoesNotThrow(() => s.JoinTransaction());
523523
}
524524
}
525+
526+
[Theory, Explicit("Bench")]
527+
public void BenchTransactionAccess(bool inTransaction)
528+
{
529+
var currentTransaction = System.Transactions.Transaction.Current;
530+
using (inTransaction ? new TransactionScope() : null)
531+
using (var s = OpenSession())
532+
{
533+
var impl = s.GetSessionImplementation();
534+
var transactionContext = impl.TransactionContext;
535+
if (inTransaction)
536+
s.JoinTransaction();
537+
538+
// warm-up
539+
for (var i = 0; i < 10; i++)
540+
currentTransaction = System.Transactions.Transaction.Current;
541+
for (var i = 0; i < 10; i++)
542+
transactionContext = impl.TransactionContext;
543+
544+
var sw = new Stopwatch();
545+
for (var j = 0; j < 4; j++)
546+
{
547+
sw.Restart();
548+
for (var i = 0; i < 10000; i++)
549+
currentTransaction = System.Transactions.Transaction.Current;
550+
sw.Stop();
551+
Assert.That(currentTransaction, inTransaction ? Is.Not.Null : Is.Null);
552+
553+
Console.WriteLine($"Current transaction reads have taken {sw.Elapsed}");
554+
sw.Restart();
555+
for (var i = 0; i < 10000; i++)
556+
transactionContext = impl.TransactionContext;
557+
sw.Stop();
558+
Assert.That(transactionContext, inTransaction ? Is.Not.Null : Is.Null);
559+
Console.WriteLine($"Transaction context reads have taken {sw.Elapsed}");
560+
}
561+
}
562+
}
525563
}
526564

527565
[TestFixture]

src/NHibernate/Async/Transaction/AdoNetWithSystemTransactionFactory.cs

-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
using NHibernate.AdoNet;
1717
using NHibernate.Engine;
1818
using NHibernate.Engine.Transaction;
19-
using NHibernate.Impl;
2019
using NHibernate.Util;
2120

2221
namespace NHibernate.Transaction

src/NHibernate/Transaction/AdoNetWithSystemTransactionFactory.cs

+9-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using NHibernate.AdoNet;
77
using NHibernate.Engine;
88
using NHibernate.Engine.Transaction;
9-
using NHibernate.Impl;
109
using NHibernate.Util;
1110

1211
namespace NHibernate.Transaction
@@ -47,14 +46,20 @@ public override void EnlistInSystemTransactionIfNeeded(ISessionImplementor sessi
4746
if (session == null)
4847
throw new ArgumentNullException(nameof(session));
4948

50-
if (!session.ConnectionManager.ShouldAutoJoinTransaction)
51-
{
49+
if (!ShouldAutoJoinSystemTransaction(session))
5250
return;
53-
}
5451

5552
JoinSystemTransaction(session, System.Transactions.Transaction.Current);
5653
}
5754

55+
private static bool ShouldAutoJoinSystemTransaction(ISessionImplementor session)
56+
{
57+
var connectionManager = session.ConnectionManager;
58+
return connectionManager.ShouldAutoJoinTransaction &&
59+
// Shortcut for avoiding accessing Transaction.Current, which is costly.
60+
(session.TransactionContext == null || connectionManager.ProcessingFromSystemTransaction);
61+
}
62+
5863
/// <inheritdoc />
5964
public override void ExplicitJoinSystemTransaction(ISessionImplementor session)
6065
{

0 commit comments

Comments
 (0)