-
-
Save andreazevedo/3758267 to your computer and use it in GitHub Desktop.
Do NHibernate Transactions rollback with parent transaction scope?
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.Data.SqlServerCe; | |
using System.IO; | |
using System.Reflection; | |
using Moq; | |
using NHibernate; | |
using NHibernate.ByteCode.Castle; | |
using NHibernate.Cfg; | |
using NHibernate.Tool.hbm2ddl; | |
namespace Tests | |
{ | |
public class SqlCeTestDatabase | |
{ | |
private static ISessionFactory _sessionFactory; | |
private static Configuration _configuration; | |
private SqlCeConnection _connection; | |
private string _connectionString; | |
protected Mock<ISessionFactory> _mockSessionFactory; | |
public SqlCeTestDatabase(Assembly hbmlAssembly,string filePath = null) | |
{ | |
filePath = filePath ?? Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"db_test.sdf"); | |
_connectionString = string.Format("Data Source={0}", filePath); | |
if (_configuration == null) | |
{ | |
try | |
{ | |
_configuration = GetConfigurationFromConnectionString(_connectionString,hbmlAssembly); | |
CreateDb(filePath); | |
} | |
catch (Exception ex) | |
{ | |
Console.WriteLine(ex.ToString()); | |
} | |
} | |
} | |
public SqlCeTestDatabase(string hbmlXml, string name, string filePath = null) | |
{ | |
filePath = filePath ?? Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"db_test.sdf"); | |
_connectionString = string.Format("Data Source={0}", filePath); | |
if (_configuration == null) | |
{ | |
try | |
{ | |
_configuration = GetConfigurationFromConnectionString(_connectionString, hbmlXml,name); | |
CreateDb(filePath); | |
} | |
catch (Exception ex) | |
{ | |
Console.WriteLine(ex.ToString()); | |
} | |
} | |
} | |
private void CreateDb(string filePath) | |
{ | |
// create the database | |
if (!File.Exists(filePath)) | |
{ | |
using (SqlCeEngine engine = new SqlCeEngine(_connectionString)) | |
{ | |
engine.CreateDatabase(); | |
} | |
} | |
_sessionFactory = _configuration.BuildSessionFactory(); | |
} | |
public Configuration GetConfigurationFromConnectionString(string connectionString, Assembly hbmlAssembly) | |
{ | |
return new Configuration() | |
.SetProperty(NHibernate.Cfg.Environment.ReleaseConnections, "on_close") | |
.SetProperty(NHibernate.Cfg.Environment.Dialect, "NHibernate.Dialect.MsSqlCeDialect") | |
.SetProperty(NHibernate.Cfg.Environment.ConnectionProvider, "NHibernate.Connection.DriverConnectionProvider") | |
.SetProperty(NHibernate.Cfg.Environment.ConnectionDriver, "NHibernate.Driver.SqlServerCeDriver") | |
.SetProperty(NHibernate.Cfg.Environment.ConnectionString, connectionString) | |
.SetProperty(NHibernate.Cfg.Environment.ProxyFactoryFactoryClass, typeof(ProxyFactoryFactory).AssemblyQualifiedName) | |
.AddAssembly(hbmlAssembly); | |
} | |
public Configuration GetConfigurationFromConnectionString(string connectionString, string hbmlXml, string name) | |
{ | |
return new Configuration() | |
.SetProperty(NHibernate.Cfg.Environment.ReleaseConnections, "on_close") | |
.SetProperty(NHibernate.Cfg.Environment.Dialect, "NHibernate.Dialect.MsSqlCeDialect") | |
.SetProperty(NHibernate.Cfg.Environment.ConnectionProvider, "NHibernate.Connection.DriverConnectionProvider") | |
.SetProperty(NHibernate.Cfg.Environment.ConnectionDriver, "NHibernate.Driver.SqlServerCeDriver") | |
.SetProperty(NHibernate.Cfg.Environment.ConnectionString, connectionString) | |
.SetProperty(NHibernate.Cfg.Environment.ProxyFactoryFactoryClass, typeof(ProxyFactoryFactory).AssemblyQualifiedName) | |
.AddXml(hbmlXml,name); | |
} | |
public virtual void SetUpNewDatabase() | |
{ | |
_connection = new SqlCeConnection(_connectionString); | |
_connection.Open(); | |
new SchemaExport(_configuration).Execute(true, true, false, _connection, System.Console.Out); | |
_mockSessionFactory = new Mock<ISessionFactory>(); | |
_mockSessionFactory.Setup(x => x.OpenSession()).Returns(() => CreateSession()); | |
_mockSessionFactory.Setup(x => x.OpenStatelessSession()).Returns(() => CreateStatelessSession()); | |
} | |
public virtual void SetUpSessionFactory() | |
{ | |
_mockSessionFactory = new Mock<ISessionFactory>(); | |
_mockSessionFactory.Setup(x => x.OpenSession()).Returns(() => CreateSession()); | |
_mockSessionFactory.Setup(x => x.OpenStatelessSession()).Returns(() => CreateStatelessSession()); | |
} | |
public ISession CreateSession() | |
{ | |
return _sessionFactory.OpenSession(_connection); | |
} | |
public IStatelessSession CreateStatelessSession() | |
{ | |
return _sessionFactory.OpenStatelessSession(_connection); | |
} | |
public ISessionFactory GetSessionFactory() | |
{ | |
return _mockSessionFactory.Object; | |
} | |
} | |
[TestClass] | |
public class TestRollbackScenarios | |
{ | |
[TestMethod] | |
public void DoNHibernateTransactionsRollbackOnParentRollback() //Fails | |
{ | |
SqlCeTestDatabase db = new SqlCeTestDatabase(@"<?xml version=""1.0"" encoding=""utf-8""?> | |
<hibernate-mapping xmlns=""urn:nhibernate-mapping-2.2"" assembly=""Tests"" namespace=""Tests""> | |
<class name=""Tests.TestEntity, Tests"" table=""TestEntities"" > | |
<id name=""Id"" column=""Id"" type=""Int32"" /> | |
</class> | |
</hibernate-mapping>", "Test"); | |
db.SetUpNewDatabase(); | |
using (var tx = new TransactionScope(TransactionScopeOption.Required)) | |
{ | |
using (var session = db.CreateSession()) | |
using(var nhTx = session.BeginTransaction()) | |
{ | |
session.Save(new TestEntity | |
{ | |
}); | |
nhTx.Commit(); | |
} | |
//no complete so should rollback | |
} | |
using (var session = db.CreateSession()) | |
{ | |
Assert.AreEqual(0, session.CreateCriteria<TestEntity>().List<TestEntity>().Count()); | |
} | |
} | |
[TestMethod] | |
public void DoTransactionsRollbackOnParentRollback() //Passes | |
{ | |
SqlCeTestDatabase db = new SqlCeTestDatabase(@"<?xml version=""1.0"" encoding=""utf-8""?> | |
<hibernate-mapping xmlns=""urn:nhibernate-mapping-2.2"" assembly=""Tests"" namespace=""Tests""> | |
<class name=""Tests.TestEntity, Tests"" table=""TestEntities"" > | |
<id name=""Id"" column=""Id"" type=""Int32"" /> | |
</class> | |
</hibernate-mapping>", "Test"); | |
db.SetUpNewDatabase(); | |
using (var tx = new TransactionScope(TransactionScopeOption.Required)) | |
{ | |
using (var childTransaction = new TransactionScope(TransactionScopeOption.Required)) | |
{ | |
using (var session = db.CreateSession()) | |
{ | |
session.Save(new TestEntity | |
{ | |
}); | |
} | |
childTransaction.Complete(); | |
} | |
//no complete so should rollback | |
} | |
using (var session = db.CreateSession()) | |
{ | |
Assert.AreEqual(0, session.CreateCriteria<TestEntity>().List<TestEntity>().Count()); | |
} | |
} | |
} | |
public class TestEntity | |
{ | |
public virtual int Id { get; set; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment