Last active
December 19, 2015 13:59
-
-
Save PeterLehmann/5966373 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Data; | |
using System.Data.SqlClient; | |
using System.Linq; | |
using System.Threading; | |
using System.Transactions; | |
using Coop.Common; | |
using Coop.Core.Domain.Entities; | |
using Coop.Core.Infrastructure; | |
using Coop.NHibernateUtils; | |
using Coop.Trio.Receipts.Core; | |
using NHibernate; | |
using NHibernate.Exceptions; | |
using NUnit.Framework; | |
using IsolationLevel = System.Transactions.IsolationLevel; | |
namespace Coop.IntegrationTests | |
{ | |
[TestFixture] | |
public class ScratchPad : TestWithIocContainerBase | |
{ | |
[Test] | |
public void Test1000TimeInSameThreadAndGetNotImplatedException() | |
{ | |
var sf1 = | |
Container.Resolve<ISessionFactory>(NhibernateCastleInstaller.GetSessionFactoryProviderKey(TrioNHibernateConfigurtion.Name)); | |
var sf2 = | |
Container.Resolve<ISessionFactory>(NhibernateCastleInstaller.GetSessionFactoryProviderKey(TrioReceiptNHibernateConfiguration.Name)); | |
var sfs = new List<ISessionFactory>{sf1,sf2}; | |
for (int i = 0; i < 1000; i++) | |
{ | |
Console.WriteLine("running for time {0}", i + 1); | |
RunATest(() => RunTrans(() => RunInDtc(sfs, s => { throw new NotImplementedException(); }))); | |
} | |
Assert.Pass(); | |
} | |
[Test] | |
public void Test1000TimeInSameThreadAndGetUniqueKey() | |
{ | |
var sf1 = | |
Container.Resolve<ISessionFactory>(NhibernateCastleInstaller.GetSessionFactoryProviderKey(TrioNHibernateConfigurtion.Name)); | |
var sf2 = | |
Container.Resolve<ISessionFactory>(NhibernateCastleInstaller.GetSessionFactoryProviderKey(TrioReceiptNHibernateConfiguration.Name)); | |
var sfs = new List<ISessionFactory> { sf1, sf2 }; | |
for (int i = 0; i < 1000; i++) | |
{ | |
Console.WriteLine("running for time {0}", i + 1); | |
RunATest(() => RunTrans(() => RunInDtc(sfs, s => | |
{ | |
var c = new Country(Guid.NewGuid(), "US", "dfsdfs", "45", "000", "dd"); | |
s.Save(c); | |
s.Transaction.Commit(); | |
}))); | |
} | |
Assert.Pass(); | |
} | |
private void RunATest(Action test) | |
{ | |
try | |
{ | |
test.Invoke(); | |
} | |
catch (NotImplementedException) | |
{ | |
} | |
catch (GenericADOException e) | |
{ | |
var exp = e.GetInnerException(); | |
var sexc = exp as SqlException; | |
if (sexc == null) | |
{ | |
throw; | |
} | |
if (sexc.Class != 14 || sexc.Number != 2627) | |
{ | |
throw; | |
} | |
} | |
} | |
private void RunTrans(Action action) | |
{ | |
using (var ts = new TransactionScope(TransactionScopeOption.RequiresNew, new TransactionOptions | |
{ | |
IsolationLevel = IsolationLevel.ReadCommitted, | |
Timeout = TimeSpan.FromMinutes(30) | |
})) | |
{ | |
var bytes = TransactionInterop.GetTransmitterPropagationToken(Transaction.Current); //force a dtc tran | |
action(); | |
ts.Complete(); | |
} | |
} | |
private static void RunInDtc(IEnumerable<ISessionFactory> sfs, Action<ISession> testAction) | |
{ | |
var sessions = new List<ISession>(); | |
try | |
{ | |
foreach (var sessionFactory in sfs) | |
{ | |
var session = sessionFactory.OpenSession(); | |
session.BeginTransaction(System.Data.IsolationLevel.ReadCommitted); | |
sessions.Add(session); | |
} | |
var s = sessions[0]; | |
testAction(s); | |
} | |
catch (Exception e) | |
{ | |
Transaction.Current.Rollback(e); | |
while (Transaction.Current.TransactionInformation.Status != TransactionStatus.Aborted) | |
{ | |
Thread.Sleep(20); | |
} | |
foreach (var iSession in sessions) | |
{ | |
if (iSession.Transaction.IsActive) | |
{ | |
try | |
{ | |
iSession.Transaction.Rollback(); | |
} | |
catch (Exception e1) | |
{ | |
Console.WriteLine(e1); | |
} | |
} | |
} | |
throw; | |
} | |
finally | |
{ | |
foreach (var session in sessions) | |
{ | |
session.Transaction.Dispose(); | |
session.Dispose(); | |
} | |
sessions.Clear(); | |
} | |
} | |
private void UseingAdo() | |
{ | |
var list = new List<Tuple<IDbConnection, IDbTransaction>>(); | |
try | |
{ | |
var tx = CreateConnection("StoreDb"); | |
list.Add(tx); | |
tx = CreateConnection("TrioPosLogStagingDb"); | |
list.Add(tx); | |
throw new NotImplementedException(); | |
} | |
catch (Exception e) | |
{ | |
Transaction.Current.Rollback(e); | |
while (Transaction.Current.TransactionInformation.Status != TransactionStatus.Aborted) | |
{ | |
Thread.Sleep(20); | |
} | |
throw; | |
} | |
finally | |
{ | |
foreach (var t in list) | |
{ | |
if(Transaction.Current.TransactionInformation.Status == TransactionStatus.Active) { | |
t.Item2.Dispose(); | |
t.Item1.Dispose(); | |
} | |
} | |
list.Clear(); | |
} | |
} | |
private static Tuple<IDbConnection, IDbTransaction> CreateConnection(string connectionString) | |
{ | |
IDbConnection connection =new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings[connectionString].ConnectionString); | |
connection.Open(); | |
var tx = connection.BeginTransaction(System.Data.IsolationLevel.ReadCommitted); | |
return Tuple.Create(connection, tx); | |
} | |
[Test] | |
public void Fun1() | |
{ | |
for (int i = 0; i < 100; i++) | |
{ | |
Console.WriteLine("running for time {0}", i + 1); | |
RunATest(() => RunTrans(UseingAdo)); | |
} | |
Assert.Pass(); | |
} | |
[TearDown] | |
public void TearDown() | |
{ | |
SqlConnection.ClearAllPools(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment