From: <aye...@us...> - 2009-01-10 02:25:10
|
Revision: 3984 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3984&view=rev Author: ayenderahien Date: 2009-01-10 02:25:05 +0000 (Sat, 10 Jan 2009) Log Message: ----------- TableHiLoGenerator - now can safely create hilo ids inside DTC transactions. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Id/TableGenerator.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1632/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1632/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1632/Model.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Modified: trunk/nhibernate/src/NHibernate/Id/TableGenerator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Id/TableGenerator.cs 2009-01-09 23:31:13 UTC (rev 3983) +++ trunk/nhibernate/src/NHibernate/Id/TableGenerator.cs 2009-01-10 02:25:05 UTC (rev 3984) @@ -13,6 +13,8 @@ namespace NHibernate.Id { + using System.Transactions; + /// <summary> /// An <see cref="IIdentifierGenerator" /> that uses a database table to store the last /// generated value. @@ -158,21 +160,27 @@ bool isSQLite = session.Factory.Dialect is SQLiteDialect; IDbConnection conn; + TransactionScope dtcTrans = null; if (isSQLite) { conn = session.Connection; } else { + // existing dtc transaction, creating a new one + // to override the ambient one + if (Transaction.Current != null) + dtcTrans = new TransactionScope(TransactionScopeOption.RequiresNew); conn = session.Factory.ConnectionProvider.GetConnection(); } + IDbTransaction trans = null; try { - IDbTransaction trans = null; if (!isSQLite) { - trans = conn.BeginTransaction(); + if(dtcTrans==null) + trans = conn.BeginTransaction(); } long result; @@ -239,7 +247,10 @@ if (!isSQLite) { - trans.Commit(); + if (dtcTrans != null) + dtcTrans.Complete(); + else + trans.Commit(); } return result; @@ -249,6 +260,8 @@ { if (!isSQLite) { + if(dtcTrans!=null) + dtcTrans.Dispose(); session.Factory.ConnectionProvider.CloseConnection(conn); } } Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1632/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1632/Fixture.cs 2009-01-09 23:31:13 UTC (rev 3983) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1632/Fixture.cs 2009-01-10 02:25:05 UTC (rev 3984) @@ -6,6 +6,8 @@ using System.Transactions; using Cache; using Cfg; + using Engine; + using Id; [TestFixture] public class Fixture : BugTestCase @@ -23,6 +25,42 @@ } [Test] + public void When_using_DTC_HiLo_knows_to_create_isolated_DTC_transaction() + { + object scalar1, scalar2; + + using (var session = sessions.OpenSession()) + using (var command = session.Connection.CreateCommand()) + { + command.CommandText = "select next_hi from hibernate_unique_key with (updlock, rowlock)"; + scalar1 = command.ExecuteScalar(); + } + + using (var tx = new TransactionScope()) + { + var generator = sessions.GetIdentifierGenerator(typeof(Person).FullName); + Assert.IsInstanceOfType(typeof(TableHiLoGenerator), generator); + + using(var session = sessions.OpenSession()) + { + var id = generator.Generate((ISessionImplementor) session, new Person()); + } + + // intentionally dispose without committing + tx.Dispose(); + } + + using (var session = sessions.OpenSession()) + using (var command = session.Connection.CreateCommand()) + { + command.CommandText = "select next_hi from hibernate_unique_key with (updlock, rowlock)"; + scalar2 = command.ExecuteScalar(); + } + + Assert.AreNotEqual(scalar1, scalar2,"HiLo must run with in its own transaction"); + } + + [Test] public void Dispose_session_inside_transaction_scope() { ISession s; Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1632/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1632/Mappings.hbm.xml 2009-01-09 23:31:13 UTC (rev 3983) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1632/Mappings.hbm.xml 2009-01-10 02:25:05 UTC (rev 3984) @@ -14,4 +14,14 @@ <property name="NumB"/> <property name="Sum" access="readonly"/> </class> + + <class name="Person"> + <cache usage="read-write" /> + + <id name="Id"> + <generator class="hilo"/> + </id> + + <property name="Name"/> + </class> </hibernate-mapping> Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1632/Model.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1632/Model.cs 2009-01-09 23:31:13 UTC (rev 3983) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1632/Model.cs 2009-01-10 02:25:05 UTC (rev 3984) @@ -14,4 +14,10 @@ } } } + + public class Person + { + public virtual int Id { get; set; } + public virtual string Name { get; set; } + } } Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-01-09 23:31:13 UTC (rev 3983) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-01-10 02:25:05 UTC (rev 3984) @@ -1591,10 +1591,6 @@ <EmbeddedResource Include="Deletetransient\Person.hbm.xml" /> <Content Include="DynamicEntity\package.html" /> <EmbeddedResource Include="NHSpecificTest\NH1632\Mappings.hbm.xml" /> - - - - <EmbeddedResource Include="NHSpecificTest\NH1612\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1549\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1521\AclassWithSpecific.hbm.xml" /> @@ -1706,4 +1702,4 @@ if exist "$(ProjectDir)hibernate.cfg.xml" (copy "$(ProjectDir)hibernate.cfg.xml" "hibernate.cfg.xml") copy /y "..\..\..\NHibernate.DomainModel\ABC.hbm.xml" "ABC.hbm.xml"</PostBuildEvent> </PropertyGroup> -</Project> +</Project> \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |