|
From: <aye...@us...> - 2009-05-22 05:38:22
|
Revision: 4353
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4353&view=rev
Author: ayenderahien
Date: 2009-05-22 05:38:20 +0000 (Fri, 22 May 2009)
Log Message:
-----------
NH-1790 - allowing SqlClientBatchingBatcher to batch non identical statements.
This means a nice perf improvement because we can put more stuff into a batch, but it should be noted that we aren't batching across different statement types.
That is, we will batch all inserts, but we will not batch inserts & updates.
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/AdoNet/AbstractBatcher.cs
trunk/nhibernate/src/NHibernate/AdoNet/SqlClientBatchingBatcher.cs
trunk/nhibernate/src/NHibernate/AdoNet/SqlClientBatchingBatcherFactory.cs
trunk/nhibernate/src/NHibernate.Test/Ado/BatcherFixture.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/Ado/AlmostSimple.cs
trunk/nhibernate/src/NHibernate.Test/Ado/AlmostSimple.hbm.xml
Modified: trunk/nhibernate/src/NHibernate/AdoNet/AbstractBatcher.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/AdoNet/AbstractBatcher.cs 2009-05-22 00:52:05 UTC (rev 4352)
+++ trunk/nhibernate/src/NHibernate/AdoNet/AbstractBatcher.cs 2009-05-22 05:38:20 UTC (rev 4353)
@@ -148,9 +148,7 @@
public IDbCommand PrepareCommand(CommandType type, SqlString sql, SqlType[] parameterTypes)
{
- // a new IDbCommand is being prepared and a new (potential) batch
- // started - so execute the current batch of commands.
- ExecuteBatch();
+ OnPreparedCommand();
// do not actually prepare the Command here - instead just generate it because
// if the command is associated with an ADO.NET Transaction/Connection while
@@ -159,6 +157,13 @@
return Generate(type, sql, parameterTypes);
}
+ protected virtual void OnPreparedCommand()
+ {
+ // a new IDbCommand is being prepared and a new (potential) batch
+ // started - so execute the current batch of commands.
+ ExecuteBatch();
+ }
+
public IDbCommand PrepareQueryCommand(CommandType type, SqlString sql, SqlType[] parameterTypes)
{
// do not actually prepare the Command here - instead just generate it because
Modified: trunk/nhibernate/src/NHibernate/AdoNet/SqlClientBatchingBatcher.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/AdoNet/SqlClientBatchingBatcher.cs 2009-05-22 00:52:05 UTC (rev 4352)
+++ trunk/nhibernate/src/NHibernate/AdoNet/SqlClientBatchingBatcher.cs 2009-05-22 05:38:20 UTC (rev 4353)
@@ -74,5 +74,12 @@
totalExpectedRowsAffected = 0;
currentBatch = new SqlClientSqlCommandSet();
}
+
+ protected override void OnPreparedCommand()
+ {
+ // SQL Server batching can handle several different commands, and
+ // that gives us a nice perf boost when mixing different queries for
+ // batching
+ }
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/AdoNet/SqlClientBatchingBatcherFactory.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/AdoNet/SqlClientBatchingBatcherFactory.cs 2009-05-22 00:52:05 UTC (rev 4352)
+++ trunk/nhibernate/src/NHibernate/AdoNet/SqlClientBatchingBatcherFactory.cs 2009-05-22 05:38:20 UTC (rev 4353)
@@ -2,7 +2,7 @@
namespace NHibernate.AdoNet
{
- internal class SqlClientBatchingBatcherFactory : IBatcherFactory
+ public class SqlClientBatchingBatcherFactory : IBatcherFactory
{
public virtual IBatcher CreateBatcher(ConnectionManager connectionManager, IInterceptor interceptor)
{
Added: trunk/nhibernate/src/NHibernate.Test/Ado/AlmostSimple.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Ado/AlmostSimple.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Ado/AlmostSimple.cs 2009-05-22 05:38:20 UTC (rev 4353)
@@ -0,0 +1,9 @@
+namespace NHibernate.Test.Ado
+{
+ public class AlmostSimple
+ {
+ public virtual int Id { get; set; }
+ public virtual string Name { get; set; }
+ public virtual double Weight { get; set; }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/Ado/AlmostSimple.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Ado/AlmostSimple.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Ado/AlmostSimple.hbm.xml 2009-05-22 05:38:20 UTC (rev 4353)
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+ assembly="NHibernate.Test"
+ namespace="NHibernate.Test.Ado">
+
+ <class name="AlmostSimple">
+ <id name="Id"/>
+ <property name="Name"/>
+ <property name="Weight"/>
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate.Test/Ado/BatcherFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Ado/BatcherFixture.cs 2009-05-22 00:52:05 UTC (rev 4352)
+++ trunk/nhibernate/src/NHibernate.Test/Ado/BatcherFixture.cs 2009-05-22 05:38:20 UTC (rev 4353)
@@ -1,6 +1,7 @@
using System.Collections;
using NHibernate.AdoNet;
using NHibernate.Cfg;
+using NHibernate.Dialect;
using NUnit.Framework;
namespace NHibernate.Test.Ado
@@ -15,7 +16,7 @@
protected override IList Mappings
{
- get { return new[] { "Ado.VerySimple.hbm.xml" }; }
+ get { return new[] { "Ado.VerySimple.hbm.xml", "Ado.AlmostSimple.hbm.xml" }; }
}
protected override void Configure(Configuration configuration)
@@ -47,6 +48,7 @@
using (s.BeginTransaction())
{
s.CreateQuery("delete from VerySimple").ExecuteUpdate();
+ s.CreateQuery("delete from AlmostSimple").ExecuteUpdate();
s.Transaction.Commit();
}
}
@@ -74,7 +76,7 @@
var vs1 = s.Get<VerySimple>(1);
var vs2 = s.Get<VerySimple>(2);
vs1.Weight -= 10;
- vs1.Weight -= 1;
+ vs2.Weight -= 1;
sessions.Statistics.Clear();
s.Update(vs1);
s.Update(vs2);
@@ -86,6 +88,45 @@
}
[Test]
+ [Description("SqlClient: The batcher should run all different INSERT queries in only one roundtrip.")]
+ public void SqlClientOneRoundTripForUpdateAndInsert()
+ {
+ if (sessions.Settings.BatcherFactory is SqlClientBatchingBatcherFactory == false)
+ Assert.Ignore("This test is for SqlClientBatchingBatcher only");
+
+ FillDb();
+
+ using(var sqlLog = new SqlLogSpy())
+ using (ISession s = sessions.OpenSession())
+ using (ITransaction tx = s.BeginTransaction())
+ {
+ s.Save(new VerySimple
+ {
+ Name = "test441",
+ Weight = 894
+ });
+
+ s.Save(new AlmostSimple
+ {
+ Name = "test441",
+ Weight = 894
+ });
+
+ tx.Commit();
+
+ var log = sqlLog.GetWholeLog();
+ //log should only contain NHibernate.SQL once, because that means
+ //that we ony generated a single batch (NHibernate.SQL log will output
+ //once per batch)
+ Assert.AreEqual(0, log.IndexOf("NHibernate.SQL"), "log should start with NHibernate.SQL");
+ Assert.AreEqual(-1, log.IndexOf("NHibernate.SQL", "NHibernate.SQL".Length), "NHibernate.SQL should only appear once in the log");
+ }
+
+ Cleanup();
+ }
+
+
+ [Test]
[Description("The batcher should run all DELETE queries in only one roundtrip.")]
public void OneRoundTripDelete()
{
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-05-22 00:52:05 UTC (rev 4352)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-05-22 05:38:20 UTC (rev 4353)
@@ -74,6 +74,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="Ado\AlmostSimple.cs" />
<Compile Include="Ado\BatcherFixture.cs" />
<Compile Include="Ado\VerySimple.cs" />
<Compile Include="Any\Address.cs" />
@@ -1822,6 +1823,7 @@
<EmbeddedResource Include="Deletetransient\Person.hbm.xml" />
<EmbeddedResource Include="BulkManipulation\SimpleClass.hbm.xml" />
<EmbeddedResource Include="Ado\VerySimple.hbm.xml" />
+ <EmbeddedResource Include="Ado\AlmostSimple.hbm.xml" />
<Content Include="DynamicEntity\package.html" />
<EmbeddedResource Include="NHSpecificTest\NH1756\Mappings.hbm.xml" />
<EmbeddedResource Include="LazyProperty\Mappings.hbm.xml" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|