|
From: <ric...@us...> - 2010-05-07 22:44:20
|
Revision: 4979
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4979&view=rev
Author: ricbrown
Date: 2010-05-07 22:44:13 +0000 (Fri, 07 May 2010)
Log Message:
-----------
Fix NH-2192 (Thread safety issue with QueryParameters.PrepareParameterTypes)
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs
trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2192/
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2192/Fixture.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2192/Mappings.hbm.xml
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2192/Model.cs
Modified: trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs 2010-05-01 22:22:06 UTC (rev 4978)
+++ trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs 2010-05-07 22:44:13 UTC (rev 4979)
@@ -304,7 +304,7 @@
if (session.EnabledFilters.Count == 0 || sql.ToString().IndexOf(ParserHelper.HqlVariablePrefix) < 0)
{
- processedSQL = sql;
+ processedSQL = sql.Copy();
return;
}
@@ -393,7 +393,7 @@
processedSQL = result.ToSqlString();
}
- private IList<Parameter> ResetParameterLocations(SqlString sqlString)
+ private IList<Parameter> FindParametersIn(SqlString sqlString)
{
IList<Parameter> sqlParameters = new List<Parameter>();
@@ -401,9 +401,7 @@
{
if (sqlParameter is Parameter)
{
- Parameter parameter = (Parameter)sqlParameter;
- parameter.ParameterPosition = null;
- sqlParameters.Add(parameter);
+ sqlParameters.Add((Parameter)sqlParameter);
}
}
@@ -441,7 +439,7 @@
int parameterIndex = 0;
int totalSpan = 0;
- IList<Parameter> sqlParameters = ResetParameterLocations(sqlString);
+ IList<Parameter> sqlParameters = FindParametersIn(sqlString);
for (int index = 0; index < PositionalParameterTypes.Length; index++)
{
Modified: trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs 2010-05-01 22:22:06 UTC (rev 4978)
+++ trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs 2010-05-07 22:44:13 UTC (rev 4979)
@@ -572,6 +572,22 @@
}
/// <summary>
+ /// Make a copy of the SqlString, with new parameter references (Placeholders)
+ /// </summary>
+ public SqlString Copy()
+ {
+ SqlString clone = Clone();
+
+ for (int i=0; i<clone.sqlParts.Length; i++)
+ {
+ if (clone.sqlParts[i] is Parameter)
+ clone.sqlParts[i] = SqlCommand.Parameter.Placeholder;
+ }
+
+ return clone;
+ }
+
+ /// <summary>
/// Returns substring of this SqlString starting with the specified
/// <paramref name="text" />. If the text is not found, returns an
/// empty, not-null SqlString.
Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2192
___________________________________________________________________
Added: bugtraq:url
+ http://jira.nhibernate.org/browse/%BUGID%
Added: bugtraq:logregex
+ NH-\d+
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2192/Fixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2192/Fixture.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2192/Fixture.cs 2010-05-07 22:44:13 UTC (rev 4979)
@@ -0,0 +1,121 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using NUnit.Framework;
+
+namespace NHibernate.Test.NHSpecificTest.NH2192
+{
+ [TestFixture]
+ public class Fixture : BugTestCase
+ {
+ protected override void OnSetUp()
+ {
+ base.OnSetUp();
+
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ s.Save(new ContentItem() { Name = "Test" });
+ s.Save(new ContentItem() { Name = "Test" });
+ s.Save(new ContentItem() { Name = "Test2" });
+ tx.Commit();
+ }
+ }
+
+ protected override void OnTearDown()
+ {
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ s.Delete("from ContentItem");
+ tx.Commit();
+ }
+
+ base.OnTearDown();
+ }
+
+ private const int _threadCount = 150;
+
+ [Test]
+ public void HqlIsThreadsafe_UsingThreads()
+ {
+ object sync = new object();
+ List<int> results = new List<int>();
+ List<Exception> exceptions = new List<Exception>();
+
+ var threads = new List<Thread>();
+
+ for (int i=0; i<_threadCount; i++)
+ {
+ var thread = new Thread(new ThreadStart(() =>
+ {
+ try
+ {
+ int result = FetchRowResults();
+ lock (sync)
+ {
+ results.Add(result);
+ }
+ }
+ catch (Exception e)
+ {
+ lock (sync)
+ {
+ exceptions.Add(e);
+ }
+ }
+ }));
+
+ threads.Add(thread);
+ }
+
+ threads.ForEach(t => t.Start());
+ threads.ForEach(t => t.Join());
+
+ if (exceptions.Count > 0)
+ throw exceptions[0];
+
+ results.ForEach(r => Assert.That(r, Is.EqualTo(2)));
+ }
+
+ [Test]
+ public void HqlIsThreadsafe_UsingPool()
+ {
+ List<Exception> exceptions = new List<Exception>();
+ Func<int> result = FetchRowResults;
+ List<IAsyncResult> results = new List<IAsyncResult>();
+
+ for (int i=0; i<_threadCount; i++)
+ results.Add(result.BeginInvoke(null, null));
+
+ results.ForEach(r =>
+ {
+ try
+ {
+ Assert.That(result.EndInvoke(r), Is.EqualTo(2));
+ }
+ catch (Exception e)
+ {
+ exceptions.Add(e);
+ }
+ });
+
+ if (exceptions.Count > 0)
+ throw exceptions[0];
+ }
+
+ private int FetchRowResults()
+ {
+ using (var s = Sfi.OpenSession())
+ {
+ var count =
+ s.CreateQuery("select ci from ContentItem ci where ci.Name = :v1")
+ .SetParameter("v1", "Test")
+ .List<ContentItem>()
+ .Count;
+
+ return count;
+ }
+ }
+ }
+}
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2192/Mappings.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2192/Mappings.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2192/Mappings.hbm.xml 2010-05-07 22:44:13 UTC (rev 4979)
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+ assembly="NHibernate.Test"
+ namespace="NHibernate.Test.NHSpecificTest.NH2192">
+
+ <class name="ContentItem">
+ <id name="Id">
+ <generator class="hilo" />
+ </id>
+ <property name="Name" type="String" />
+ </class>
+
+</hibernate-mapping>
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2192/Model.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2192/Model.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2192/Model.cs 2010-05-07 22:44:13 UTC (rev 4979)
@@ -0,0 +1,8 @@
+namespace NHibernate.Test.NHSpecificTest.NH2192
+{
+ public class ContentItem
+ {
+ 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 2010-05-01 22:22:06 UTC (rev 4978)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-05-07 22:44:13 UTC (rev 4979)
@@ -710,6 +710,8 @@
<Compile Include="NHSpecificTest\NH2077\Model.cs" />
<Compile Include="NHSpecificTest\NH2113\Fixture.cs" />
<Compile Include="NHSpecificTest\NH2113\Model.cs" />
+ <Compile Include="NHSpecificTest\NH2192\Fixture.cs" />
+ <Compile Include="NHSpecificTest\NH2192\Model.cs" />
<Compile Include="NHSpecificTest\NH473\Child.cs" />
<Compile Include="NHSpecificTest\NH473\Fixture.cs" />
<Compile Include="NHSpecificTest\NH473\Parent.cs" />
@@ -2132,6 +2134,7 @@
<EmbeddedResource Include="CfgTest\Loquacious\EntityToCache.hbm.xml" />
<EmbeddedResource Include="DriverTest\SqlServerCeEntity.hbm.xml" />
<Content Include="DynamicEntity\package.html" />
+ <EmbeddedResource Include="NHSpecificTest\NH2192\Mappings.hbm.xml" />
<EmbeddedResource Include="ListIndex\SimpleOneToMany.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\SessionIdLoggingContextTest\Mappings.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\NH2113\Mappings.hbm.xml" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|