misc updates to make compiler happy and comment out a few failing tests, see JIRA issue for more information
1476 lines
59 KiB
C#
1476 lines
59 KiB
C#
#region License
|
|
|
|
/*
|
|
* Copyright © 2002-2007 the original author or authors.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#endregion
|
|
|
|
#region Imports
|
|
|
|
using System;
|
|
using System.Data;
|
|
using System.Threading;
|
|
using NUnit.Framework;
|
|
using Rhino.Mocks;
|
|
using Spring.Dao;
|
|
using Spring.Data.Common;
|
|
using Spring.Data.Core;
|
|
using Spring.Data.Support;
|
|
using Spring.Support;
|
|
using Spring.Transaction;
|
|
using Spring.Transaction.Support;
|
|
|
|
#endregion
|
|
|
|
namespace Spring.Data
|
|
{
|
|
/// <summary>
|
|
/// This class contains tests for AdoPlatformTransactionManager
|
|
/// </summary>
|
|
/// <author>Mark Pollack</author>
|
|
[TestFixture]
|
|
public class AdoPlatformTransactionManagerTests
|
|
{
|
|
private MockRepository mocks;
|
|
|
|
[SetUp]
|
|
public void Setup()
|
|
{
|
|
mocks = new MockRepository();
|
|
}
|
|
|
|
[TearDown]
|
|
public void TearDown()
|
|
{
|
|
Assert.IsTrue(TransactionSynchronizationManager.ResourceDictionary.Count == 0);
|
|
Assert.IsFalse(TransactionSynchronizationManager.SynchronizationActive);
|
|
Assert.IsFalse(TransactionSynchronizationManager.CurrentTransactionReadOnly);
|
|
Assert.IsFalse(TransactionSynchronizationManager.ActualTransactionActive);
|
|
}
|
|
|
|
[Test]
|
|
public void TransactionCommit()
|
|
{
|
|
#region Mock setup
|
|
IDbProvider dbProvider = (IDbProvider) mocks.CreateMock(typeof (IDbProvider));
|
|
IDbConnection connection = (IDbConnection) mocks.CreateMock(typeof (IDbConnection));
|
|
IDbTransaction transaction = (IDbTransaction) mocks.CreateMock(typeof (IDbTransaction));
|
|
|
|
using (mocks.Ordered())
|
|
{
|
|
Expect.Call(dbProvider.CreateConnection()).Return(connection);
|
|
connection.Open();
|
|
LastCall.On(connection).Repeat.Once();
|
|
Expect.Call(connection.BeginTransaction(IsolationLevel.ReadCommitted)).Return(transaction);
|
|
//standard tx timeout.
|
|
transaction.Commit();
|
|
LastCall.On(transaction).Repeat.Once();
|
|
connection.Dispose();
|
|
}
|
|
|
|
#endregion
|
|
|
|
mocks.ReplayAll();
|
|
|
|
AdoPlatformTransactionManager tm = new AdoPlatformTransactionManager(dbProvider);
|
|
|
|
TransactionTemplate tt = new TransactionTemplate(tm);
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
Assert.IsTrue(!TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");
|
|
|
|
tt.Execute(new TransactionCommitTxCallback(dbProvider));
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
Assert.IsTrue(!TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");
|
|
|
|
mocks.VerifyAll();
|
|
}
|
|
|
|
[Test]
|
|
public void TransactionRollback()
|
|
{
|
|
#region Mock Setup
|
|
|
|
IDbProvider dbProvider = (IDbProvider) mocks.CreateMock(typeof (IDbProvider));
|
|
IDbConnection connection = (IDbConnection) mocks.CreateMock(typeof (IDbConnection));
|
|
IDbTransaction transaction = (IDbTransaction) mocks.CreateMock(typeof (IDbTransaction));
|
|
|
|
using (mocks.Ordered())
|
|
{
|
|
Expect.Call(dbProvider.CreateConnection()).Return(connection);
|
|
connection.Open();
|
|
LastCall.On(connection).Repeat.Once();
|
|
Expect.Call(connection.BeginTransaction(IsolationLevel.ReadCommitted)).Return(transaction);
|
|
//standard tx timeout.
|
|
transaction.Rollback();
|
|
LastCall.On(transaction).Repeat.Once();
|
|
|
|
connection.Dispose();
|
|
}
|
|
|
|
#endregion
|
|
|
|
mocks.ReplayAll();
|
|
|
|
AdoPlatformTransactionManager tm = new AdoPlatformTransactionManager(dbProvider);
|
|
TransactionTemplate tt = new TransactionTemplate(tm);
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
Assert.IsTrue(!TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");
|
|
|
|
Exception ex = new ArgumentException("test exception");
|
|
try
|
|
{
|
|
tt.Execute(new TransactionRollbackTxCallback(dbProvider, ex));
|
|
Assert.Fail("Should have thrown exception");
|
|
}
|
|
catch (ArgumentException e)
|
|
{
|
|
Assert.AreEqual(ex, e);
|
|
}
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
Assert.IsTrue(!TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");
|
|
|
|
|
|
mocks.VerifyAll();
|
|
}
|
|
|
|
[Test]
|
|
public void ParticipatingTransactionWithRollbackOnly()
|
|
{
|
|
IDbProvider dbProvider = (IDbProvider) mocks.CreateMock(typeof (IDbProvider));
|
|
IDbConnection connection = (IDbConnection) mocks.CreateMock(typeof (IDbConnection));
|
|
IDbTransaction transaction = (IDbTransaction) mocks.CreateMock(typeof (IDbTransaction));
|
|
|
|
using (mocks.Ordered())
|
|
{
|
|
Expect.Call(dbProvider.CreateConnection()).Return(connection);
|
|
connection.Open();
|
|
LastCall.On(connection).Repeat.Once();
|
|
Expect.Call(connection.BeginTransaction(IsolationLevel.ReadCommitted)).Return(transaction);
|
|
//standard tx timeout.
|
|
transaction.Rollback();
|
|
LastCall.On(transaction).Repeat.Once();
|
|
connection.Dispose();
|
|
}
|
|
mocks.ReplayAll();
|
|
|
|
AdoPlatformTransactionManager tm = new AdoPlatformTransactionManager(dbProvider);
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
Assert.IsTrue(!TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");
|
|
|
|
ITransactionStatus ts = tm.GetTransaction(new DefaultTransactionDefinition());
|
|
TestTransactionSynchronization synch =
|
|
new TestTransactionSynchronization(dbProvider, TransactionSynchronizationStatus.Rolledback);
|
|
TransactionSynchronizationManager.RegisterSynchronization(synch);
|
|
|
|
bool outerTransactionBoundaryReached = false;
|
|
try
|
|
{
|
|
Assert.IsTrue(ts.IsNewTransaction);
|
|
TransactionTemplate tt = new TransactionTemplate(tm);
|
|
TransactionTemplate tt2 = new TransactionTemplate(tm);
|
|
tt.Execute(new ParticipatingTxWithRollbackOnlyTxCallback(tt2, dbProvider));
|
|
outerTransactionBoundaryReached = true;
|
|
tm.Commit(ts);
|
|
Assert.Fail("Should have thrown UnexpectedRollbackException");
|
|
}
|
|
catch (UnexpectedRollbackException)
|
|
{
|
|
// expected
|
|
if (!outerTransactionBoundaryReached)
|
|
{
|
|
tm.Rollback(ts);
|
|
}
|
|
Assert.IsTrue(outerTransactionBoundaryReached);
|
|
}
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
Assert.IsFalse(synch.beforeCommitCalled);
|
|
Assert.IsTrue(synch.beforeCompletionCalled);
|
|
Assert.IsFalse(synch.afterCommitCalled);
|
|
Assert.IsTrue(synch.afterCompletionCalled);
|
|
|
|
mocks.VerifyAll();
|
|
}
|
|
|
|
[Test]
|
|
[Ignore]
|
|
public void ParticipatingTransactionWithTransactionStartedFromSynch()
|
|
{
|
|
}
|
|
|
|
[Test]
|
|
[Ignore]
|
|
public void ParticipatingTransactionWithRollbackOnlyAndInnerSynch()
|
|
{
|
|
}
|
|
|
|
[Test]
|
|
public void PropagationRequiresNewWithExistingTransaction()
|
|
{
|
|
#region Mock Setup
|
|
IDbProvider dbProvider = (IDbProvider) mocks.CreateMock(typeof (IDbProvider));
|
|
IDbConnection connection = (IDbConnection) mocks.CreateMock(typeof (IDbConnection));
|
|
IDbTransaction transaction = (IDbTransaction) mocks.CreateMock(typeof (IDbTransaction));
|
|
|
|
Expect.Call(dbProvider.CreateConnection()).Return(connection).Repeat.Twice();
|
|
connection.Open();
|
|
LastCall.On(connection).Repeat.Twice();
|
|
Expect.Call(connection.BeginTransaction(IsolationLevel.ReadCommitted)).Return(transaction).Repeat.Twice();
|
|
//standard tx timeout.
|
|
transaction.Rollback();
|
|
LastCall.On(transaction).Repeat.Once();
|
|
|
|
transaction.Commit();
|
|
LastCall.On(transaction).Repeat.Once();
|
|
|
|
connection.Dispose();
|
|
LastCall.On(connection).Repeat.Twice();
|
|
|
|
#endregion
|
|
|
|
mocks.ReplayAll();
|
|
|
|
AdoPlatformTransactionManager tm = new AdoPlatformTransactionManager(dbProvider);
|
|
|
|
TransactionTemplate tt = new TransactionTemplate(tm);
|
|
tt.PropagationBehavior = TransactionPropagation.RequiresNew;
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
Assert.IsTrue(!TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");
|
|
|
|
tt.Execute(new PropagationRequiresNewWithExistingTransactionCallback(tt, dbProvider));
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
|
|
mocks.VerifyAll();
|
|
}
|
|
|
|
[Test]
|
|
public void PropagationRequiresNewWithExistingTransactionAndUnrelatedDataSource()
|
|
{
|
|
IDbProvider dbProvider = (IDbProvider) mocks.CreateMock(typeof (IDbProvider));
|
|
IDbConnection connection = (IDbConnection) mocks.CreateMock(typeof (IDbConnection));
|
|
IDbTransaction transaction = (IDbTransaction) mocks.CreateMock(typeof (IDbTransaction));
|
|
|
|
Expect.Call(dbProvider.CreateConnection()).Return(connection);
|
|
connection.Open();
|
|
LastCall.On(connection).Repeat.Once();
|
|
Expect.Call(connection.BeginTransaction(IsolationLevel.ReadCommitted)).Return(transaction);
|
|
transaction.Commit();
|
|
LastCall.On(transaction).Repeat.Once();
|
|
connection.Dispose();
|
|
|
|
IDbProvider dbProvider2 = (IDbProvider) mocks.CreateMock(typeof (IDbProvider));
|
|
IDbConnection connection2 = (IDbConnection) mocks.CreateMock(typeof (IDbConnection));
|
|
IDbTransaction transaction2 = (IDbTransaction) mocks.CreateMock(typeof (IDbTransaction));
|
|
|
|
Expect.Call(dbProvider2.CreateConnection()).Return(connection2);
|
|
connection2.Open();
|
|
LastCall.On(connection2).Repeat.Once();
|
|
Expect.Call(connection2.BeginTransaction(IsolationLevel.ReadCommitted)).Return(transaction2);
|
|
transaction2.Rollback();
|
|
LastCall.On(transaction2).Repeat.Once();
|
|
connection2.Dispose();
|
|
|
|
mocks.ReplayAll();
|
|
|
|
AdoPlatformTransactionManager tm = new AdoPlatformTransactionManager(dbProvider);
|
|
TransactionTemplate tt = new TransactionTemplate(tm);
|
|
tt.PropagationBehavior = TransactionPropagation.RequiresNew;
|
|
|
|
AdoPlatformTransactionManager tm2 = new AdoPlatformTransactionManager(dbProvider2);
|
|
TransactionTemplate tt2 = new TransactionTemplate(tm2);
|
|
tt2.PropagationBehavior = TransactionPropagation.RequiresNew;
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider2), "Hasn't thread db provider");
|
|
Assert.IsTrue(!TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");
|
|
|
|
|
|
tt.Execute(new PropagationRequiresNewWithExistingTransactionCallback(tt2, dbProvider));
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider2), "Hasn't thread db provider");
|
|
|
|
mocks.VerifyAll();
|
|
}
|
|
|
|
[Test]
|
|
public void PropagationRequiresNewWithExistingTransactionAndUnrelatedFailingDataSource()
|
|
{
|
|
#region Mock Setup
|
|
IDbProvider dbProvider = (IDbProvider)mocks.CreateMock(typeof(IDbProvider));
|
|
IDbConnection connection = (IDbConnection)mocks.CreateMock(typeof(IDbConnection));
|
|
IDbTransaction transaction = (IDbTransaction)mocks.CreateMock(typeof(IDbTransaction));
|
|
|
|
Expect.Call(dbProvider.CreateConnection()).Return(connection);
|
|
connection.Open();
|
|
LastCall.On(connection).Repeat.Once();
|
|
Expect.Call(connection.BeginTransaction(IsolationLevel.ReadCommitted)).Return(transaction);
|
|
transaction.Rollback();
|
|
LastCall.On(transaction).Repeat.Once();
|
|
connection.Dispose();
|
|
|
|
IDbProvider dbProvider2 = (IDbProvider)mocks.CreateMock(typeof(IDbProvider));
|
|
IDbConnection connection2 = (IDbConnection)mocks.CreateMock(typeof(IDbConnection));
|
|
|
|
Expect.Call(dbProvider2.CreateConnection()).Return(connection2);
|
|
connection2.Open();
|
|
Exception failure = new Exception("can't open connection");
|
|
LastCall.On(connection2).Throw(failure);
|
|
|
|
#endregion
|
|
|
|
mocks.ReplayAll();
|
|
|
|
AdoPlatformTransactionManager tm = new AdoPlatformTransactionManager(dbProvider);
|
|
TransactionTemplate tt = new TransactionTemplate(tm);
|
|
tt.PropagationBehavior = TransactionPropagation.RequiresNew;
|
|
|
|
AdoPlatformTransactionManager tm2 = new AdoPlatformTransactionManager(dbProvider2);
|
|
tm2.TransactionSynchronization = TransactionSynchronizationState.Never;
|
|
TransactionTemplate tt2 = new TransactionTemplate(tm2);
|
|
tt2.PropagationBehavior = TransactionPropagation.RequiresNew;
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider2), "Hasn't thread db provider");
|
|
Assert.IsTrue(!TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");
|
|
|
|
try
|
|
{
|
|
tt.Execute(
|
|
new PropagationRequiresNewWithExistingTransactionAndUnrelatedFailingDataSourceCallback(tt2));
|
|
Assert.Fail("Should have thrown CannotCreateTransactionException");
|
|
} catch(CannotCreateTransactionException ex)
|
|
{
|
|
Assert.AreSame(failure, ex.InnerException);
|
|
}
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider2), "Hasn't thread db provider");
|
|
mocks.VerifyAll();
|
|
}
|
|
|
|
[Test]
|
|
public void PropagationNotSupportedWithExistingTransaction()
|
|
{
|
|
#region Mock Setup
|
|
IDbProvider dbProvider = (IDbProvider)mocks.CreateMock(typeof(IDbProvider));
|
|
IDbConnection connection = (IDbConnection)mocks.CreateMock(typeof(IDbConnection));
|
|
IDbTransaction transaction = (IDbTransaction)mocks.CreateMock(typeof(IDbTransaction));
|
|
|
|
using (mocks.Ordered())
|
|
{
|
|
Expect.Call(dbProvider.CreateConnection()).Return(connection);
|
|
connection.Open();
|
|
LastCall.On(connection).Repeat.Once();
|
|
Expect.Call(connection.BeginTransaction(IsolationLevel.ReadCommitted)).Return(transaction);
|
|
//standard tx timeout.
|
|
transaction.Commit();
|
|
LastCall.On(transaction).Repeat.Once();
|
|
connection.Dispose();
|
|
}
|
|
#endregion
|
|
|
|
mocks.ReplayAll();
|
|
|
|
AdoPlatformTransactionManager tm = new AdoPlatformTransactionManager(dbProvider);
|
|
TransactionTemplate tt = new TransactionTemplate(tm);
|
|
tt.PropagationBehavior = TransactionPropagation.RequiresNew;
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
Assert.IsTrue(!TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");
|
|
|
|
tt.Execute(new PropagationNotSupportedWithExistingTransactionCallback(tt, dbProvider));
|
|
|
|
mocks.VerifyAll();
|
|
}
|
|
|
|
[Test]
|
|
public void PropagationNeverWithExistingTransaction()
|
|
{
|
|
#region Mock Setup
|
|
IDbProvider dbProvider = (IDbProvider)mocks.CreateMock(typeof(IDbProvider));
|
|
IDbConnection connection = (IDbConnection)mocks.CreateMock(typeof(IDbConnection));
|
|
IDbTransaction transaction = (IDbTransaction)mocks.CreateMock(typeof(IDbTransaction));
|
|
|
|
using (mocks.Ordered())
|
|
{
|
|
Expect.Call(dbProvider.CreateConnection()).Return(connection);
|
|
connection.Open();
|
|
LastCall.On(connection).Repeat.Once();
|
|
Expect.Call(connection.BeginTransaction(IsolationLevel.ReadCommitted)).Return(transaction);
|
|
//standard tx timeout.
|
|
transaction.Rollback();
|
|
LastCall.On(transaction).Repeat.Once();
|
|
|
|
connection.Dispose();
|
|
}
|
|
#endregion
|
|
|
|
mocks.ReplayAll();
|
|
|
|
AdoPlatformTransactionManager tm = new AdoPlatformTransactionManager(dbProvider);
|
|
TransactionTemplate tt = new TransactionTemplate(tm);
|
|
tt.PropagationBehavior = TransactionPropagation.RequiresNew;
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
Assert.IsTrue(!TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");
|
|
|
|
try
|
|
{
|
|
tt.Execute(new PropagationNeverWithExistingTransactionCallback(tt));
|
|
Assert.Fail("Should have thrown IllegalTransactionStateException");
|
|
} catch (IllegalTransactionStateException)
|
|
{
|
|
//expected.
|
|
}
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
|
|
mocks.VerifyAll();
|
|
}
|
|
|
|
[Test]
|
|
public void PropagationRequiresNewWithExistingConnection()
|
|
{
|
|
#region Mock Setup
|
|
|
|
IDbProvider dbProvider = (IDbProvider)mocks.CreateMock(typeof(IDbProvider));
|
|
IDbConnection connection = (IDbConnection)mocks.CreateMock(typeof(IDbConnection));
|
|
|
|
Expect.Call(dbProvider.CreateConnection()).Return(connection);
|
|
connection.Open();
|
|
LastCall.On(connection).Repeat.Once();
|
|
connection.Dispose();
|
|
|
|
IDbConnection connection2 = (IDbConnection)mocks.CreateMock(typeof(IDbConnection));
|
|
IDbTransaction transaction2 = (IDbTransaction)mocks.CreateMock(typeof(IDbTransaction));
|
|
|
|
Expect.Call(dbProvider.CreateConnection()).Return(connection2);
|
|
connection2.Open();
|
|
LastCall.On(connection2).Repeat.Once();
|
|
Expect.Call(connection2.BeginTransaction(IsolationLevel.ReadCommitted)).Return(transaction2);
|
|
transaction2.Commit();
|
|
LastCall.On(transaction2).Repeat.Once();
|
|
connection2.Dispose();
|
|
|
|
#endregion
|
|
|
|
mocks.ReplayAll();
|
|
|
|
AdoPlatformTransactionManager tm = new AdoPlatformTransactionManager(dbProvider);
|
|
TransactionTemplate tt = new TransactionTemplate(tm);
|
|
tt.PropagationBehavior = TransactionPropagation.Supports;
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
Assert.IsTrue(!TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");
|
|
|
|
tt.Execute(new PropagationRequiresNewWithExistingConnectionCallback(tt, connection, connection2, dbProvider));
|
|
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
|
|
mocks.VerifyAll();
|
|
}
|
|
|
|
[Test]
|
|
public void TransactionWithIsolation()
|
|
{
|
|
#region Mock setup
|
|
IDbProvider dbProvider = (IDbProvider)mocks.CreateMock(typeof(IDbProvider));
|
|
IDbConnection connection = (IDbConnection)mocks.CreateMock(typeof(IDbConnection));
|
|
IDbTransaction transaction = (IDbTransaction)mocks.CreateMock(typeof(IDbTransaction));
|
|
|
|
using (mocks.Ordered())
|
|
{
|
|
Expect.Call(dbProvider.CreateConnection()).Return(connection);
|
|
connection.Open();
|
|
LastCall.On(connection).Repeat.Once();
|
|
Expect.Call(connection.BeginTransaction(IsolationLevel.Serializable)).Return(transaction);
|
|
//standard tx timeout.
|
|
transaction.Commit();
|
|
LastCall.On(transaction).Repeat.Once();
|
|
connection.Dispose();
|
|
}
|
|
|
|
#endregion
|
|
|
|
mocks.ReplayAll();
|
|
|
|
AdoPlatformTransactionManager tm = new AdoPlatformTransactionManager(dbProvider);
|
|
TransactionTemplate tt = new TransactionTemplate(tm);
|
|
tt.PropagationBehavior = TransactionPropagation.RequiresNew;
|
|
tt.TransactionIsolationLevel = IsolationLevel.Serializable;
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
|
|
tt.Execute(new TransactionCommitTxCallback(dbProvider));
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
|
|
mocks.VerifyAll();
|
|
}
|
|
|
|
[Test]
|
|
public void TransactionWithLongTimeout()
|
|
{
|
|
DoTransactionWithTimeout(10);
|
|
}
|
|
|
|
[Test]
|
|
public void TransactionWithShortTimeout()
|
|
{
|
|
DoTransactionWithTimeout(1);
|
|
}
|
|
|
|
private void DoTransactionWithTimeout(int timeout)
|
|
{
|
|
#region Mock setup
|
|
|
|
IDbProvider dbProvider = (IDbProvider)mocks.CreateMock(typeof(IDbProvider));
|
|
IDbConnection connection = (IDbConnection)mocks.CreateMock(typeof(IDbConnection));
|
|
IDbTransaction transaction = (IDbTransaction)mocks.CreateMock(typeof(IDbTransaction));
|
|
IDbCommand command = (IDbCommand) mocks.CreateMock(typeof (IDbCommand));
|
|
|
|
using (mocks.Ordered())
|
|
{
|
|
Expect.Call(dbProvider.CreateConnection()).Return(connection);
|
|
connection.Open();
|
|
|
|
LastCall.On(connection).Repeat.Once();
|
|
Expect.Call(connection.BeginTransaction(IsolationLevel.ReadCommitted)).Return(transaction);
|
|
Expect.Call(connection.CreateCommand()).Return(command);
|
|
command.CommandText = "some SQL statement";
|
|
LastCall.On(command).Repeat.Once();
|
|
if (timeout > 1)
|
|
{
|
|
command.CommandTimeout = (timeout - 1);
|
|
transaction.Commit();
|
|
} else
|
|
{
|
|
transaction.Rollback();
|
|
}
|
|
LastCall.On(transaction).Repeat.Once();
|
|
connection.Dispose();
|
|
}
|
|
|
|
#endregion
|
|
|
|
mocks.ReplayAll();
|
|
|
|
AdoPlatformTransactionManager tm = new AdoPlatformTransactionManager(dbProvider);
|
|
TransactionTemplate tt = new TransactionTemplate(tm);
|
|
tt.TransactionTimeout = timeout;
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
|
|
try
|
|
{
|
|
tt.Execute(new TransactionWithTimeoutCallback(dbProvider));
|
|
if (timeout <= 1)
|
|
{
|
|
Assert.Fail("Should have thrown TransactionTimedOutException");
|
|
}
|
|
} catch (TransactionTimedOutException)
|
|
{
|
|
if (timeout <=1 )
|
|
{
|
|
//expected
|
|
} else
|
|
{
|
|
throw;
|
|
}
|
|
}
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
|
|
mocks.VerifyAll();
|
|
}
|
|
|
|
[Test]
|
|
public void TransactionWithExceptionOnBegin()
|
|
{
|
|
#region Mock setup
|
|
IDbProvider dbProvider = (IDbProvider)mocks.CreateMock(typeof(IDbProvider));
|
|
|
|
// CreateConnection is called in AdoPlatformTransactionManager.DoBegin
|
|
Expect.Call(dbProvider.CreateConnection()).Throw(new TestSqlException("Cannot begin", "314"));
|
|
|
|
|
|
#endregion
|
|
|
|
mocks.ReplayAll();
|
|
|
|
AdoPlatformTransactionManager tm = new AdoPlatformTransactionManager(dbProvider);
|
|
TransactionTemplate tt = new TransactionTemplate(tm);
|
|
try
|
|
{
|
|
tt.Execute(new TransactionDelegate(TransactionWithExceptionNoOp));
|
|
} catch (CannotCreateTransactionException)
|
|
{
|
|
// expected
|
|
}
|
|
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
|
|
mocks.VerifyAll();
|
|
}
|
|
|
|
private object TransactionWithExceptionNoOp(ITransactionStatus status)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
[Test]
|
|
public void TransactionWithExceptionOnCommit()
|
|
{
|
|
#region Mock setup
|
|
IDbProvider dbProvider = (IDbProvider)mocks.CreateMock(typeof(IDbProvider));
|
|
IDbConnection connection = (IDbConnection)mocks.CreateMock(typeof(IDbConnection));
|
|
IDbTransaction transaction = (IDbTransaction)mocks.CreateMock(typeof(IDbTransaction));
|
|
|
|
using (mocks.Ordered())
|
|
{
|
|
Expect.Call(dbProvider.CreateConnection()).Return(connection);
|
|
connection.Open();
|
|
LastCall.On(connection).Repeat.Once();
|
|
Expect.Call(connection.BeginTransaction(IsolationLevel.ReadCommitted)).Return(transaction);
|
|
//standard tx timeout.
|
|
transaction.Commit();
|
|
LastCall.On(transaction).Throw(new TestSqlException("Cannot commit", "314"));
|
|
connection.Dispose();
|
|
}
|
|
|
|
#endregion
|
|
|
|
mocks.ReplayAll();
|
|
|
|
AdoPlatformTransactionManager tm = new AdoPlatformTransactionManager(dbProvider);
|
|
TransactionTemplate tt = new TransactionTemplate(tm);
|
|
|
|
try
|
|
{
|
|
tt.Execute(new TransactionDelegate(TransactionWithExceptionNoOp));
|
|
} catch (TransactionSystemException)
|
|
{
|
|
//expected
|
|
}
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
mocks.VerifyAll();
|
|
|
|
}
|
|
|
|
|
|
[Test]
|
|
public void TransactionWithExceptionOnCommitAndRollbackOnCommitFailure()
|
|
{
|
|
#region Mock Setup
|
|
IDbProvider dbProvider = (IDbProvider)mocks.CreateMock(typeof(IDbProvider));
|
|
IDbConnection connection = (IDbConnection)mocks.CreateMock(typeof(IDbConnection));
|
|
IDbTransaction transaction = (IDbTransaction)mocks.CreateMock(typeof(IDbTransaction));
|
|
|
|
using (mocks.Ordered())
|
|
{
|
|
Expect.Call(dbProvider.CreateConnection()).Return(connection);
|
|
connection.Open();
|
|
LastCall.On(connection).Repeat.Once();
|
|
Expect.Call(connection.BeginTransaction(IsolationLevel.ReadCommitted)).Return(transaction);
|
|
transaction.Commit();
|
|
LastCall.On(transaction).Throw(new TestSqlException("Cannot commit", "314"));
|
|
|
|
transaction.Rollback();
|
|
LastCall.On(transaction).Repeat.Once();
|
|
|
|
connection.Dispose();
|
|
}
|
|
#endregion
|
|
mocks.ReplayAll();
|
|
|
|
AdoPlatformTransactionManager tm = new AdoPlatformTransactionManager(dbProvider);
|
|
tm.RollbackOnCommitFailure = true;
|
|
TransactionTemplate tt = new TransactionTemplate(tm);
|
|
|
|
try
|
|
{
|
|
tt.Execute(new TransactionDelegate(TransactionWithExceptionNoOp));
|
|
}
|
|
catch (TransactionSystemException)
|
|
{
|
|
//expected
|
|
}
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
|
|
mocks.VerifyAll();
|
|
}
|
|
|
|
[Test]
|
|
public void TransactionWithExceptionOnRollback()
|
|
{
|
|
#region Mock Setup
|
|
|
|
IDbProvider dbProvider = (IDbProvider)mocks.CreateMock(typeof(IDbProvider));
|
|
IDbConnection connection = (IDbConnection)mocks.CreateMock(typeof(IDbConnection));
|
|
IDbTransaction transaction = (IDbTransaction)mocks.CreateMock(typeof(IDbTransaction));
|
|
|
|
using (mocks.Ordered())
|
|
{
|
|
Expect.Call(dbProvider.CreateConnection()).Return(connection);
|
|
connection.Open();
|
|
LastCall.On(connection).Repeat.Once();
|
|
Expect.Call(connection.BeginTransaction(IsolationLevel.ReadCommitted)).Return(transaction);
|
|
//standard tx timeout.
|
|
transaction.Rollback();
|
|
LastCall.On(transaction).Throw(new TestSqlException("Cannot commit", "314"));
|
|
|
|
connection.Dispose();
|
|
}
|
|
|
|
#endregion
|
|
|
|
mocks.ReplayAll();
|
|
|
|
AdoPlatformTransactionManager tm = new AdoPlatformTransactionManager(dbProvider);
|
|
TransactionTemplate tt = new TransactionTemplate(tm);
|
|
|
|
try
|
|
{
|
|
tt.Execute(new TransactionDelegate(TransactionWithExceptionOnRollbackMethod));
|
|
}
|
|
catch (TransactionSystemException)
|
|
{
|
|
//expected
|
|
}
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
|
|
mocks.VerifyAll();
|
|
|
|
}
|
|
|
|
private object TransactionWithExceptionOnRollbackMethod(ITransactionStatus status)
|
|
{
|
|
status.SetRollbackOnly();
|
|
return null;
|
|
}
|
|
|
|
[Test]
|
|
public void TransactionWithPropagationSupports()
|
|
{
|
|
IDbProvider dbProvider = (IDbProvider)mocks.CreateMock(typeof(IDbProvider));
|
|
|
|
mocks.ReplayAll();
|
|
|
|
AdoPlatformTransactionManager tm = new AdoPlatformTransactionManager(dbProvider);
|
|
TransactionTemplate tt = new TransactionTemplate(tm);
|
|
tt.PropagationBehavior = TransactionPropagation.Supports;
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
|
|
tt.Execute(new TransactionWithPropagationSupportsCallback(dbProvider));
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
mocks.VerifyAll();
|
|
}
|
|
|
|
[Test]
|
|
public void TransactionWithPropagationNotSupported()
|
|
{
|
|
IDbProvider dbProvider = (IDbProvider)mocks.CreateMock(typeof(IDbProvider));
|
|
|
|
mocks.ReplayAll();
|
|
|
|
AdoPlatformTransactionManager tm = new AdoPlatformTransactionManager(dbProvider);
|
|
TransactionTemplate tt = new TransactionTemplate(tm);
|
|
tt.PropagationBehavior = TransactionPropagation.NotSupported;
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
|
|
tt.Execute(new TransactionWithPropagationNotSupportedCallback(dbProvider));
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
mocks.VerifyAll();
|
|
}
|
|
|
|
[Test]
|
|
public void TransactionWithPropagationNever()
|
|
{
|
|
IDbProvider dbProvider = (IDbProvider)mocks.CreateMock(typeof(IDbProvider));
|
|
|
|
mocks.ReplayAll();
|
|
|
|
AdoPlatformTransactionManager tm = new AdoPlatformTransactionManager(dbProvider);
|
|
TransactionTemplate tt = new TransactionTemplate(tm);
|
|
tt.PropagationBehavior = TransactionPropagation.Never;
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
|
|
tt.Execute(new TransactionWithPropagationNotSupportedCallback(dbProvider));
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
mocks.VerifyAll();
|
|
}
|
|
|
|
[Test]
|
|
public void ExistingTransactionWithPropagationNestedNotSupported()
|
|
{
|
|
#region Mock setup
|
|
IDbProvider dbProvider = (IDbProvider)mocks.CreateMock(typeof(IDbProvider));
|
|
IDbConnection connection = (IDbConnection)mocks.CreateMock(typeof(IDbConnection));
|
|
IDbTransaction transaction = (IDbTransaction)mocks.CreateMock(typeof(IDbTransaction));
|
|
|
|
using (mocks.Ordered())
|
|
{
|
|
Expect.Call(dbProvider.CreateConnection()).Return(connection);
|
|
connection.Open();
|
|
LastCall.On(connection).Repeat.Once();
|
|
Expect.Call(connection.BeginTransaction(IsolationLevel.ReadCommitted)).Return(transaction);
|
|
|
|
transaction.Rollback();
|
|
LastCall.On(transaction).Repeat.Once();
|
|
connection.Dispose();
|
|
}
|
|
|
|
#endregion
|
|
|
|
mocks.ReplayAll();
|
|
|
|
AdoPlatformTransactionManager tm = new AdoPlatformTransactionManager(dbProvider);
|
|
TransactionTemplate tt = new TransactionTemplate(tm);
|
|
tt.PropagationBehavior = TransactionPropagation.Nested;
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
Assert.IsTrue(!TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");
|
|
|
|
try
|
|
{
|
|
tt.Execute(new ExistingTransactionWithPropagationNestedCallback(dbProvider, tt));
|
|
Assert.Fail("Should have thrown NestedTransactionNotSupportedException");
|
|
} catch (NestedTransactionNotSupportedException)
|
|
{
|
|
// expected
|
|
}
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
mocks.VerifyAll();
|
|
}
|
|
|
|
[Test]
|
|
public void TransactionWithPropagationNested()
|
|
{
|
|
#region Mock setup
|
|
IDbProvider dbProvider = (IDbProvider)mocks.CreateMock(typeof(IDbProvider));
|
|
IDbConnection connection = (IDbConnection)mocks.CreateMock(typeof(IDbConnection));
|
|
IDbTransaction transaction = (IDbTransaction)mocks.CreateMock(typeof(IDbTransaction));
|
|
|
|
using (mocks.Ordered())
|
|
{
|
|
Expect.Call(dbProvider.CreateConnection()).Return(connection);
|
|
connection.Open();
|
|
LastCall.On(connection).Repeat.Once();
|
|
Expect.Call(connection.BeginTransaction(IsolationLevel.ReadCommitted)).Return(transaction);
|
|
//standard tx timeout.
|
|
transaction.Commit();
|
|
LastCall.On(transaction).Repeat.Once();
|
|
connection.Dispose();
|
|
}
|
|
|
|
#endregion
|
|
|
|
mocks.ReplayAll();
|
|
|
|
AdoPlatformTransactionManager tm = new AdoPlatformTransactionManager(dbProvider);
|
|
TransactionTemplate tt = new TransactionTemplate(tm);
|
|
tt.PropagationBehavior = TransactionPropagation.Nested;
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
Assert.IsTrue(!TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");
|
|
|
|
|
|
tt.Execute(new TransactionDelegate(TransactionWithPropagationNestedMethod));
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
mocks.VerifyAll();
|
|
|
|
|
|
}
|
|
|
|
private object TransactionWithPropagationNestedMethod(ITransactionStatus status)
|
|
{
|
|
Assert.IsTrue(status.IsNewTransaction, "Is new transaction");
|
|
return null;
|
|
}
|
|
|
|
[Test]
|
|
public void TransactionWithPropagationNestedAndRollback()
|
|
{
|
|
#region Mock setup
|
|
IDbProvider dbProvider = (IDbProvider)mocks.CreateMock(typeof(IDbProvider));
|
|
IDbConnection connection = (IDbConnection)mocks.CreateMock(typeof(IDbConnection));
|
|
IDbTransaction transaction = (IDbTransaction)mocks.CreateMock(typeof(IDbTransaction));
|
|
|
|
using (mocks.Ordered())
|
|
{
|
|
Expect.Call(dbProvider.CreateConnection()).Return(connection);
|
|
connection.Open();
|
|
LastCall.On(connection).Repeat.Once();
|
|
Expect.Call(connection.BeginTransaction(IsolationLevel.ReadCommitted)).Return(transaction);
|
|
transaction.Rollback();
|
|
LastCall.On(transaction).Repeat.Once();
|
|
connection.Dispose();
|
|
}
|
|
|
|
#endregion
|
|
|
|
mocks.ReplayAll();
|
|
|
|
AdoPlatformTransactionManager tm = new AdoPlatformTransactionManager(dbProvider);
|
|
TransactionTemplate tt = new TransactionTemplate(tm);
|
|
tt.PropagationBehavior = TransactionPropagation.Nested;
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
Assert.IsTrue(!TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");
|
|
|
|
|
|
tt.Execute(new TransactionDelegate(TransactionWithPropagationNestedAndRollbackMethod));
|
|
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(dbProvider), "Hasn't thread db provider");
|
|
mocks.VerifyAll();
|
|
|
|
|
|
}
|
|
|
|
private object TransactionWithPropagationNestedAndRollbackMethod(ITransactionStatus status)
|
|
{
|
|
Assert.IsTrue(status.IsNewTransaction, "Is new transaction");
|
|
status.SetRollbackOnly();
|
|
return null;
|
|
}
|
|
}
|
|
|
|
internal class ExistingTransactionWithPropagationNestedCallback : ITransactionCallback
|
|
{
|
|
private IDbProvider dbProvider;
|
|
private TransactionTemplate tt;
|
|
|
|
public ExistingTransactionWithPropagationNestedCallback(IDbProvider dbProvider, TransactionTemplate transactionTemplate)
|
|
{
|
|
this.dbProvider = dbProvider;
|
|
tt = transactionTemplate;
|
|
}
|
|
|
|
public object DoInTransaction(ITransactionStatus status)
|
|
{
|
|
Assert.IsTrue(status.IsNewTransaction, "Is new transaction");
|
|
//TODO: Note no support for savepoints at this time (1.1), so can't check that a savepoint isn't present.
|
|
|
|
tt.Execute(new ExistingTransactionWithPropagationNestedCallback2(dbProvider));
|
|
|
|
Assert.IsTrue(status.IsNewTransaction, "Is new transaction");
|
|
//TODO: Note no support for savepoints at this time (1.1), so can't check that a savepoint isn't present.
|
|
return null;
|
|
}
|
|
}
|
|
|
|
internal class ExistingTransactionWithPropagationNestedCallback2 : ITransactionCallback
|
|
{
|
|
private IDbProvider dbProvider;
|
|
|
|
public ExistingTransactionWithPropagationNestedCallback2(IDbProvider provider)
|
|
{
|
|
dbProvider = provider;
|
|
}
|
|
|
|
public object DoInTransaction(ITransactionStatus status)
|
|
{
|
|
Assert.IsTrue(TransactionSynchronizationManager.HasResource(dbProvider), "Has thread db provider");
|
|
Assert.IsTrue(TransactionSynchronizationManager.SynchronizationActive, "Synchronizations active");
|
|
Assert.IsTrue(!status.IsNewTransaction, "Isn't new transaction");
|
|
//TODO: Note no support for savepoints at this time (1.1), so can't check that a savepoint is present.
|
|
return null;
|
|
}
|
|
}
|
|
|
|
#region Supporting class for TransactionWithPropagationNotSupported
|
|
internal class TransactionWithPropagationNotSupportedCallback : ITransactionCallback
|
|
{
|
|
private IDbProvider provider;
|
|
|
|
public TransactionWithPropagationNotSupportedCallback(IDbProvider provider)
|
|
{
|
|
this.provider = provider;
|
|
}
|
|
|
|
public object DoInTransaction(ITransactionStatus status)
|
|
{
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(provider), "Hasn't thread db provider");
|
|
Assert.IsTrue(!status.IsNewTransaction, "Is not new transaction");
|
|
return null;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Supporting class for TransactionWithPropagationSupports
|
|
internal class TransactionWithPropagationSupportsCallback : ITransactionCallback
|
|
{
|
|
private IDbProvider provider;
|
|
|
|
public TransactionWithPropagationSupportsCallback(IDbProvider provider)
|
|
{
|
|
this.provider = provider;
|
|
}
|
|
|
|
public object DoInTransaction(ITransactionStatus status)
|
|
{
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(provider), "Hasn't thread db provider");
|
|
Assert.IsTrue(!status.IsNewTransaction,"Is not new transaction");
|
|
Assert.IsFalse(TransactionSynchronizationManager.CurrentTransactionReadOnly);
|
|
Assert.IsFalse(TransactionSynchronizationManager.ActualTransactionActive);
|
|
return null;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
|
|
#region Supporting class for TransactionWithTimeout
|
|
|
|
internal class TransactionWithTimeoutCallback : ITransactionCallback
|
|
{
|
|
private IDbProvider provider;
|
|
public TransactionWithTimeoutCallback(IDbProvider provider)
|
|
{
|
|
this.provider = provider;
|
|
}
|
|
|
|
public object DoInTransaction(ITransactionStatus status)
|
|
{
|
|
try
|
|
{
|
|
Thread.Sleep(1500);
|
|
} catch (Exception)
|
|
{
|
|
|
|
}
|
|
try
|
|
{
|
|
IDbConnection con = ConnectionUtils.GetConnection(provider);
|
|
IDbCommand cmd = con.CreateCommand();
|
|
cmd.CommandText = "some SQL statement";
|
|
ConnectionUtils.ApplyTransactionTimeout(cmd, provider);
|
|
|
|
} catch (Exception e)
|
|
{
|
|
if (e.GetType() != typeof(TransactionTimedOutException))
|
|
{
|
|
throw new DataAccessResourceFailureException("", e);
|
|
}
|
|
throw;
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Supporting class for PropagationRequiresNewWithExistingConnection
|
|
|
|
internal class PropagationRequiresNewWithExistingConnectionCallback : ITransactionCallback
|
|
{
|
|
private TransactionTemplate tt;
|
|
private IDbProvider dbProvider;
|
|
private IDbConnection connection;
|
|
private IDbConnection connection2;
|
|
|
|
public PropagationRequiresNewWithExistingConnectionCallback(TransactionTemplate transactionTemplate, IDbConnection connection, IDbConnection connection2, IDbProvider provider)
|
|
{
|
|
tt = transactionTemplate;
|
|
this.connection = connection;
|
|
this.connection2 = connection2;
|
|
dbProvider = provider;
|
|
}
|
|
|
|
public object DoInTransaction(ITransactionStatus status)
|
|
{
|
|
Assert.IsTrue(TransactionSynchronizationManager.SynchronizationActive, "Synchronizations active");
|
|
Assert.AreSame(connection, ConnectionUtils.GetConnection(dbProvider));
|
|
Assert.AreSame(connection, ConnectionUtils.GetConnection(dbProvider));
|
|
tt.PropagationBehavior = TransactionPropagation.RequiresNew;
|
|
tt.ReadOnly = true;
|
|
tt.Execute(new PropagationRequiresNewWithExistingConnectionCallback2(dbProvider, connection2));
|
|
Assert.AreSame(connection, ConnectionUtils.GetConnection(dbProvider));
|
|
return null;
|
|
}
|
|
}
|
|
|
|
internal class PropagationRequiresNewWithExistingConnectionCallback2 : ITransactionCallback
|
|
{
|
|
private IDbProvider dbProvider;
|
|
private IDbConnection connection2;
|
|
|
|
|
|
public PropagationRequiresNewWithExistingConnectionCallback2(IDbProvider dbProvider, IDbConnection connection2)
|
|
{
|
|
this.dbProvider = dbProvider;
|
|
this.connection2 = connection2;
|
|
}
|
|
|
|
public object DoInTransaction(ITransactionStatus status)
|
|
{
|
|
Assert.IsTrue(TransactionSynchronizationManager.HasResource(dbProvider), "Has thread db provider");
|
|
Assert.IsTrue(TransactionSynchronizationManager.SynchronizationActive, "Synchronizations active");
|
|
Assert.IsTrue(status.IsNewTransaction, "Is new transaction");
|
|
Assert.AreSame(connection2, ConnectionUtils.GetConnection(dbProvider));
|
|
Assert.AreSame(connection2, ConnectionUtils.GetConnection(dbProvider));
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Supporting classes for PropagationNeverWithExistingTransaction
|
|
|
|
internal class PropagationNeverWithExistingTransactionCallback : ITransactionCallback
|
|
{
|
|
private TransactionTemplate innerTxTemplate;
|
|
|
|
public PropagationNeverWithExistingTransactionCallback(TransactionTemplate transactionTemplate)
|
|
{
|
|
innerTxTemplate = transactionTemplate;
|
|
}
|
|
|
|
|
|
public object DoInTransaction(ITransactionStatus status)
|
|
{
|
|
Assert.IsTrue(status.IsNewTransaction, "Is new transaction");
|
|
innerTxTemplate.PropagationBehavior = TransactionPropagation.Never;
|
|
innerTxTemplate.Execute(new PropagationNeverWithExistingTransactionCallback2());
|
|
Assert.Fail("Should have thrown IllegalTransactionStateException");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
internal class PropagationNeverWithExistingTransactionCallback2 : ITransactionCallback
|
|
{
|
|
|
|
public object DoInTransaction(ITransactionStatus status)
|
|
{
|
|
Assert.Fail("Should have thrown IllegalTransactionStateException");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Supporting classes for PropagationNotSupportedWithExistingTransaction
|
|
|
|
internal class PropagationNotSupportedWithExistingTransactionCallback : ITransactionCallback
|
|
{
|
|
private TransactionTemplate innerTxTemplate;
|
|
private IDbProvider dbProvider;
|
|
|
|
public PropagationNotSupportedWithExistingTransactionCallback(TransactionTemplate transactionTemplate, IDbProvider provider)
|
|
{
|
|
innerTxTemplate = transactionTemplate;
|
|
dbProvider = provider;
|
|
}
|
|
|
|
public object DoInTransaction(ITransactionStatus status)
|
|
{
|
|
Assert.IsTrue(status.IsNewTransaction, "Is new transaction");
|
|
Assert.IsTrue(TransactionSynchronizationManager.SynchronizationActive, "Synchronization active");
|
|
Assert.IsFalse(TransactionSynchronizationManager.CurrentTransactionReadOnly);
|
|
innerTxTemplate.PropagationBehavior = TransactionPropagation.NotSupported;
|
|
innerTxTemplate.Execute(new PropagationNotSupportedWithExistingTransactionCallback2(dbProvider));
|
|
Assert.IsTrue(status.IsNewTransaction, "Is new transaction");
|
|
Assert.IsFalse(TransactionSynchronizationManager.CurrentTransactionReadOnly);
|
|
Assert.IsTrue(TransactionSynchronizationManager.ActualTransactionActive);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
internal class PropagationNotSupportedWithExistingTransactionCallback2 : ITransactionCallback
|
|
{
|
|
private IDbProvider provider;
|
|
|
|
public PropagationNotSupportedWithExistingTransactionCallback2(IDbProvider provider)
|
|
{
|
|
this.provider = provider;
|
|
}
|
|
|
|
public object DoInTransaction(ITransactionStatus status)
|
|
{
|
|
Assert.IsTrue(!TransactionSynchronizationManager.HasResource(provider), "Hasn't thread db provider");
|
|
Assert.IsTrue(TransactionSynchronizationManager.SynchronizationActive);
|
|
Assert.IsTrue(!status.IsNewTransaction, "Isn't new transaction");
|
|
Assert.IsFalse(TransactionSynchronizationManager.CurrentTransactionReadOnly);
|
|
Assert.IsFalse(TransactionSynchronizationManager.ActualTransactionActive);
|
|
status.SetRollbackOnly();
|
|
return null;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Supporting class for PropagationRequiresNewWithExistingTransactionAndUnrelatedFailingDataSource
|
|
|
|
internal class PropagationRequiresNewWithExistingTransactionAndUnrelatedFailingDataSourceCallback : ITransactionCallback
|
|
{
|
|
private TransactionTemplate innerTxTemplate;
|
|
|
|
|
|
public PropagationRequiresNewWithExistingTransactionAndUnrelatedFailingDataSourceCallback(TransactionTemplate transactionTemplate)
|
|
{
|
|
innerTxTemplate = transactionTemplate;
|
|
}
|
|
|
|
public object DoInTransaction(ITransactionStatus status)
|
|
{
|
|
Assert.IsTrue(status.IsNewTransaction, "Is new transaction");
|
|
Assert.IsTrue(TransactionSynchronizationManager.SynchronizationActive, "Synchronization active");
|
|
Assert.IsFalse(TransactionSynchronizationManager.CurrentTransactionReadOnly);
|
|
Assert.IsTrue(TransactionSynchronizationManager.ActualTransactionActive);
|
|
innerTxTemplate.Execute(new PropagationRequiresNewWithExistingTransactionAndUnrelatedFailingDataSourceCallback2());
|
|
return null;
|
|
}
|
|
}
|
|
|
|
internal class PropagationRequiresNewWithExistingTransactionAndUnrelatedFailingDataSourceCallback2 : ITransactionCallback
|
|
{
|
|
public object DoInTransaction(ITransactionStatus status)
|
|
{
|
|
status.SetRollbackOnly();
|
|
return null;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Supporting class for PropagationRequiresNewWithExistingTransaction
|
|
|
|
internal class PropagationRequiresNewWithExistingTransactionCallback : ITransactionCallback
|
|
{
|
|
private TransactionTemplate innerTxTemplate;
|
|
private IDbProvider dbProvider;
|
|
|
|
public PropagationRequiresNewWithExistingTransactionCallback(TransactionTemplate transactionTemplate,
|
|
IDbProvider provider)
|
|
{
|
|
innerTxTemplate = transactionTemplate;
|
|
dbProvider = provider;
|
|
}
|
|
|
|
public object DoInTransaction(ITransactionStatus status)
|
|
{
|
|
Assert.IsTrue(status.IsNewTransaction, "Is new transaction");
|
|
Assert.IsTrue(TransactionSynchronizationManager.SynchronizationActive, "Synchronization active");
|
|
Assert.IsFalse(TransactionSynchronizationManager.CurrentTransactionReadOnly);
|
|
Assert.IsTrue(TransactionSynchronizationManager.ActualTransactionActive);
|
|
innerTxTemplate.Execute(new PropagationRequiresNewWithExistingTransactionCallback2(dbProvider));
|
|
|
|
Assert.IsTrue(status.IsNewTransaction, "Is new transaction");
|
|
Assert.IsFalse(TransactionSynchronizationManager.CurrentTransactionReadOnly);
|
|
Assert.IsTrue(TransactionSynchronizationManager.ActualTransactionActive);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
internal class PropagationRequiresNewWithExistingTransactionCallback2 : ITransactionCallback
|
|
{
|
|
private IDbProvider dbProvider;
|
|
|
|
public PropagationRequiresNewWithExistingTransactionCallback2(IDbProvider dbProvider)
|
|
{
|
|
this.dbProvider = dbProvider;
|
|
}
|
|
|
|
public object DoInTransaction(ITransactionStatus status)
|
|
{
|
|
Assert.IsTrue(TransactionSynchronizationManager.HasResource(dbProvider), "Has thread connection");
|
|
Assert.IsTrue(TransactionSynchronizationManager.SynchronizationActive, "Synchronization active");
|
|
Assert.IsTrue(status.IsNewTransaction, "Is new transaction");
|
|
Assert.IsFalse(TransactionSynchronizationManager.CurrentTransactionReadOnly);
|
|
Assert.IsTrue(TransactionSynchronizationManager.ActualTransactionActive);
|
|
status.SetRollbackOnly();
|
|
return null;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Supporting class for TransactionCommit test
|
|
|
|
internal class TransactionCommitTxCallback : ITransactionCallback
|
|
{
|
|
private IDbProvider provider;
|
|
|
|
public TransactionCommitTxCallback(IDbProvider provider)
|
|
{
|
|
this.provider = provider;
|
|
}
|
|
|
|
public object DoInTransaction(ITransactionStatus status)
|
|
{
|
|
Assert.IsTrue(TransactionSynchronizationManager.HasResource(provider), "Has thread db provider");
|
|
Assert.IsTrue(TransactionSynchronizationManager.SynchronizationActive);
|
|
Assert.IsTrue(status.IsNewTransaction, "Is new transaction");
|
|
Assert.IsTrue(TransactionSynchronizationManager.ActualTransactionActive);
|
|
Assert.IsFalse(TransactionSynchronizationManager.CurrentTransactionReadOnly);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Supporting class for TransactionRollback test
|
|
|
|
internal class TransactionRollbackTxCallback : ITransactionCallback
|
|
{
|
|
private IDbProvider provider;
|
|
private Exception exception;
|
|
|
|
public TransactionRollbackTxCallback(IDbProvider provider, Exception exception)
|
|
{
|
|
this.provider = provider;
|
|
this.exception = exception;
|
|
}
|
|
|
|
public object DoInTransaction(ITransactionStatus status)
|
|
{
|
|
Assert.IsTrue(TransactionSynchronizationManager.HasResource(provider), "Hasn't thread db provider");
|
|
Assert.IsTrue(TransactionSynchronizationManager.SynchronizationActive);
|
|
Assert.IsTrue(status.IsNewTransaction, "Is new transaction");
|
|
throw exception;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Supporting class for ParticipatingTxWithRollbackOnly test
|
|
|
|
internal class ParticipatingTxWithRollbackOnlyTxCallback : ITransactionCallback
|
|
{
|
|
private TransactionTemplate innerTxTemplate;
|
|
private IDbProvider dbProvider;
|
|
|
|
|
|
public ParticipatingTxWithRollbackOnlyTxCallback(TransactionTemplate transactionTemplate, IDbProvider dbProvider)
|
|
{
|
|
innerTxTemplate = transactionTemplate;
|
|
this.dbProvider = dbProvider;
|
|
}
|
|
|
|
public object DoInTransaction(ITransactionStatus status)
|
|
{
|
|
Assert.IsTrue(!status.IsNewTransaction, "Is existing transaction");
|
|
Assert.IsFalse(status.RollbackOnly, "Is not rollback-only");
|
|
innerTxTemplate.Execute(new ParticipatingTxWithRollbackOnlyTxCallback2(dbProvider));
|
|
Assert.IsTrue(!status.IsNewTransaction, "Is existing transaction");
|
|
Assert.IsTrue(status.RollbackOnly, "Is rollback-only");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
internal class ParticipatingTxWithRollbackOnlyTxCallback2 : ITransactionCallback
|
|
{
|
|
private IDbProvider dbProvider;
|
|
|
|
public ParticipatingTxWithRollbackOnlyTxCallback2(IDbProvider dbProvider)
|
|
{
|
|
this.dbProvider = dbProvider;
|
|
}
|
|
|
|
public object DoInTransaction(ITransactionStatus status)
|
|
{
|
|
Assert.IsTrue(TransactionSynchronizationManager.HasResource(dbProvider), "Has thread connection");
|
|
Assert.IsTrue(TransactionSynchronizationManager.SynchronizationActive, "Synchronization active");
|
|
Assert.IsTrue(!status.IsNewTransaction, "Is existing transaction");
|
|
status.SetRollbackOnly();
|
|
return null;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region Helper class
|
|
|
|
internal class TestTransactionSynchronization : ITransactionSynchronization
|
|
{
|
|
private IDbProvider provider;
|
|
private TransactionSynchronizationStatus status;
|
|
|
|
public bool beforeCommitCalled;
|
|
public bool beforeCompletionCalled;
|
|
public bool afterCommitCalled;
|
|
public bool afterCompletionCalled;
|
|
|
|
public TestTransactionSynchronization(IDbProvider provider,
|
|
TransactionSynchronizationStatus synchronizationStatus)
|
|
{
|
|
this.provider = provider;
|
|
status = synchronizationStatus;
|
|
}
|
|
|
|
|
|
public void Suspend()
|
|
{
|
|
}
|
|
|
|
public void Resume()
|
|
{
|
|
}
|
|
|
|
public void BeforeCommit(bool readOnly)
|
|
{
|
|
if (status == TransactionSynchronizationStatus.Committed)
|
|
{
|
|
Assert.Fail("Should never be called");
|
|
}
|
|
Assert.IsFalse(beforeCommitCalled);
|
|
beforeCommitCalled = true;
|
|
}
|
|
|
|
public void AfterCommit()
|
|
{
|
|
if (status != TransactionSynchronizationStatus.Committed)
|
|
{
|
|
Assert.Fail("Should never be called");
|
|
}
|
|
Assert.IsFalse(afterCommitCalled);
|
|
afterCommitCalled = true;
|
|
}
|
|
|
|
public void BeforeCompletion()
|
|
{
|
|
Assert.IsFalse(beforeCompletionCalled);
|
|
beforeCompletionCalled = true;
|
|
}
|
|
|
|
public void AfterCompletion(TransactionSynchronizationStatus syncStatus)
|
|
{
|
|
Assert.IsFalse(afterCompletionCalled);
|
|
afterCompletionCalled = true;
|
|
Assert.IsTrue(syncStatus == status);
|
|
Assert.IsTrue(TransactionSynchronizationManager.HasResource(provider));
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
} |