Starting to craft LocalDataSourceJobStore for Spring managed transactions

This commit is contained in:
lahma
2008-07-31 13:54:19 +00:00
parent 34582d9bbb
commit 0c1ab68f93
5 changed files with 494 additions and 32 deletions

View File

@@ -0,0 +1,147 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Core.2005", "..\..\src\Spring\Spring.Core\Spring.Core.2005.csproj", "{710961A3-0DF4-49E4-A26E-F5B9C044AC84}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Aop.2005", "..\..\src\Spring\Spring.Aop\Spring.Aop.2005.csproj", "{3A3A4E65-45A6-4B20-B460-0BEDC302C02C}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F04753EF-7A1B-4837-AB63-8C0821E8155D}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
ProjectSection(SolutionItems) = preProject
Spring.build = Spring.build
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Data.2005", "..\..\src\Spring\Spring.Data\Spring.Data.2005.csproj", "{AE00E5AB-C39A-436F-86D2-33BFE33E2E40}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Data.Tests.2005", "..\..\test\Spring\Spring.Data.Tests\Spring.Data.Tests.2005.csproj", "{ACD39D47-1811-40FA-9E7E-5DEA5B9CE6C0}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Core.Tests.2005", "..\..\test\Spring\Spring.Core.Tests\Spring.Core.Tests.2005.csproj", "{44B16BAA-6DF8-447C-9D7F-3AD3D854D904}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Scheduling.Quartz.2005", "..\..\src\Spring\Spring.Scheduling.Quartz\Spring.Scheduling.Quartz.2005.csproj", "{E823D54C-CE82-4868-929F-5F95A999F61E}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Scheduling.Quartz.Tests.2005", "..\..\test\Spring\Spring.Scheduling.Quartz.Tests\Spring.Scheduling.Quartz.Tests.2005.csproj", "{9FE720ED-2BD9-4FB9-89C8-FFFA4A491CB5}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|.NET = Debug|.NET
Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms
Release|.NET = Release|.NET
Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{710961A3-0DF4-49E4-A26E-F5B9C044AC84}.Debug|.NET.ActiveCfg = Debug|Any CPU
{710961A3-0DF4-49E4-A26E-F5B9C044AC84}.Debug|.NET.Build.0 = Debug|Any CPU
{710961A3-0DF4-49E4-A26E-F5B9C044AC84}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{710961A3-0DF4-49E4-A26E-F5B9C044AC84}.Debug|Any CPU.Build.0 = Debug|Any CPU
{710961A3-0DF4-49E4-A26E-F5B9C044AC84}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{710961A3-0DF4-49E4-A26E-F5B9C044AC84}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{710961A3-0DF4-49E4-A26E-F5B9C044AC84}.Release|.NET.ActiveCfg = Release|Any CPU
{710961A3-0DF4-49E4-A26E-F5B9C044AC84}.Release|.NET.Build.0 = Release|Any CPU
{710961A3-0DF4-49E4-A26E-F5B9C044AC84}.Release|Any CPU.ActiveCfg = Release|Any CPU
{710961A3-0DF4-49E4-A26E-F5B9C044AC84}.Release|Any CPU.Build.0 = Release|Any CPU
{710961A3-0DF4-49E4-A26E-F5B9C044AC84}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{710961A3-0DF4-49E4-A26E-F5B9C044AC84}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{3A3A4E65-45A6-4B20-B460-0BEDC302C02C}.Debug|.NET.ActiveCfg = Debug|Any CPU
{3A3A4E65-45A6-4B20-B460-0BEDC302C02C}.Debug|.NET.Build.0 = Debug|Any CPU
{3A3A4E65-45A6-4B20-B460-0BEDC302C02C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3A3A4E65-45A6-4B20-B460-0BEDC302C02C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3A3A4E65-45A6-4B20-B460-0BEDC302C02C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{3A3A4E65-45A6-4B20-B460-0BEDC302C02C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{3A3A4E65-45A6-4B20-B460-0BEDC302C02C}.Release|.NET.ActiveCfg = Release|Any CPU
{3A3A4E65-45A6-4B20-B460-0BEDC302C02C}.Release|.NET.Build.0 = Release|Any CPU
{3A3A4E65-45A6-4B20-B460-0BEDC302C02C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3A3A4E65-45A6-4B20-B460-0BEDC302C02C}.Release|Any CPU.Build.0 = Release|Any CPU
{3A3A4E65-45A6-4B20-B460-0BEDC302C02C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{3A3A4E65-45A6-4B20-B460-0BEDC302C02C}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{AE00E5AB-C39A-436F-86D2-33BFE33E2E40}.Debug|.NET.ActiveCfg = Debug|Any CPU
{AE00E5AB-C39A-436F-86D2-33BFE33E2E40}.Debug|.NET.Build.0 = Debug|Any CPU
{AE00E5AB-C39A-436F-86D2-33BFE33E2E40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AE00E5AB-C39A-436F-86D2-33BFE33E2E40}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AE00E5AB-C39A-436F-86D2-33BFE33E2E40}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{AE00E5AB-C39A-436F-86D2-33BFE33E2E40}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{AE00E5AB-C39A-436F-86D2-33BFE33E2E40}.Release|.NET.ActiveCfg = Release|Any CPU
{AE00E5AB-C39A-436F-86D2-33BFE33E2E40}.Release|.NET.Build.0 = Release|Any CPU
{AE00E5AB-C39A-436F-86D2-33BFE33E2E40}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AE00E5AB-C39A-436F-86D2-33BFE33E2E40}.Release|Any CPU.Build.0 = Release|Any CPU
{AE00E5AB-C39A-436F-86D2-33BFE33E2E40}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{AE00E5AB-C39A-436F-86D2-33BFE33E2E40}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{ACD39D47-1811-40FA-9E7E-5DEA5B9CE6C0}.Debug|.NET.ActiveCfg = Debug|Any CPU
{ACD39D47-1811-40FA-9E7E-5DEA5B9CE6C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ACD39D47-1811-40FA-9E7E-5DEA5B9CE6C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ACD39D47-1811-40FA-9E7E-5DEA5B9CE6C0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{ACD39D47-1811-40FA-9E7E-5DEA5B9CE6C0}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{ACD39D47-1811-40FA-9E7E-5DEA5B9CE6C0}.Release|.NET.ActiveCfg = Release|Any CPU
{ACD39D47-1811-40FA-9E7E-5DEA5B9CE6C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ACD39D47-1811-40FA-9E7E-5DEA5B9CE6C0}.Release|Any CPU.Build.0 = Release|Any CPU
{ACD39D47-1811-40FA-9E7E-5DEA5B9CE6C0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{ACD39D47-1811-40FA-9E7E-5DEA5B9CE6C0}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{44B16BAA-6DF8-447C-9D7F-3AD3D854D904}.Debug|.NET.ActiveCfg = Debug|Any CPU
{44B16BAA-6DF8-447C-9D7F-3AD3D854D904}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{44B16BAA-6DF8-447C-9D7F-3AD3D854D904}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44B16BAA-6DF8-447C-9D7F-3AD3D854D904}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{44B16BAA-6DF8-447C-9D7F-3AD3D854D904}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{44B16BAA-6DF8-447C-9D7F-3AD3D854D904}.Release|.NET.ActiveCfg = Release|Any CPU
{44B16BAA-6DF8-447C-9D7F-3AD3D854D904}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44B16BAA-6DF8-447C-9D7F-3AD3D854D904}.Release|Any CPU.Build.0 = Release|Any CPU
{44B16BAA-6DF8-447C-9D7F-3AD3D854D904}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{44B16BAA-6DF8-447C-9D7F-3AD3D854D904}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{E823D54C-CE82-4868-929F-5F95A999F61E}.Debug|.NET.ActiveCfg = Debug|Any CPU
{E823D54C-CE82-4868-929F-5F95A999F61E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E823D54C-CE82-4868-929F-5F95A999F61E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E823D54C-CE82-4868-929F-5F95A999F61E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{E823D54C-CE82-4868-929F-5F95A999F61E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{E823D54C-CE82-4868-929F-5F95A999F61E}.Release|.NET.ActiveCfg = Release|Any CPU
{E823D54C-CE82-4868-929F-5F95A999F61E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E823D54C-CE82-4868-929F-5F95A999F61E}.Release|Any CPU.Build.0 = Release|Any CPU
{E823D54C-CE82-4868-929F-5F95A999F61E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{E823D54C-CE82-4868-929F-5F95A999F61E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{9FE720ED-2BD9-4FB9-89C8-FFFA4A491CB5}.Debug|.NET.ActiveCfg = Debug|Any CPU
{9FE720ED-2BD9-4FB9-89C8-FFFA4A491CB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9FE720ED-2BD9-4FB9-89C8-FFFA4A491CB5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9FE720ED-2BD9-4FB9-89C8-FFFA4A491CB5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{9FE720ED-2BD9-4FB9-89C8-FFFA4A491CB5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{9FE720ED-2BD9-4FB9-89C8-FFFA4A491CB5}.Release|.NET.ActiveCfg = Release|Any CPU
{9FE720ED-2BD9-4FB9-89C8-FFFA4A491CB5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9FE720ED-2BD9-4FB9-89C8-FFFA4A491CB5}.Release|Any CPU.Build.0 = Release|Any CPU
{9FE720ED-2BD9-4FB9-89C8-FFFA4A491CB5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{9FE720ED-2BD9-4FB9-89C8-FFFA4A491CB5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
NAntAddinLastFileName = Spring.build
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,114 @@
/*
* 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.
*/
using Quartz;
using Quartz.Impl.AdoJobStore;
using Quartz.Spi;
using Quartz.Util;
using Spring.Data.Support;
namespace Spring.Scheduling.Quartz
{
/// <summary>
/// Subclass of Quartz's JobStoreCMT class that delegates to a Spring-managed
/// DataSource instead of using a Quartz-managed connection pool. This JobStore
/// will be used if SchedulerFactoryBean's "dbProvider" property is set.
///</summary>
/// <remarks>
/// <p>Supports both transactional and non-transactional DataSource access.
/// With a non-XA DataSource and local Spring transactions, a single DataSource
/// argument is sufficient. In case of an XA DataSource and global JTA transactions,
/// SchedulerFactoryBean's "nonTransactionalDataSource" property should be set,
/// passing in a non-XA DataSource that will not participate in global transactions.</p>
///
/// <p>Operations performed by this JobStore will properly participate in any
/// kind of Spring-managed transaction, as it uses Spring's DataSourceUtils
/// connection handling methods that are aware of a current transaction.</p>
///
/// <p>Note that all Quartz Scheduler operations that affect the persistent
/// job store should usually be performed within active transactions,
/// as they assume to get proper locks etc.</p>
/// </remarks>
/// <author>Juergen Hoeller</author>
/// <author>Marko Lahma (.NET)</author>
/// <seealso cref="SchedulerFactoryObject#DbProvider" />
/// <seealso cref="ConnectionUtils.GetConnection" />
/// <seealso cref="ConnectionUtils.DisposeConnection" />
public class LocalDataSourceJobStore : JobStoreSupport
{
/**
* Name used for the transactional ConnectionProvider for Quartz.
* This provider will delegate to the local Spring-managed DataSource.
* @see org.quartz.utils.DBConnectionManager#addConnectionProvider
* @see SchedulerFactoryBean#setDataSource
*/
public const string TX_DATA_SOURCE_PREFIX = "springTxDataSource.";
private Data.Common.IDbProvider dbProvider;
public Data.Common.IDbProvider DbProvider
{
get { return dbProvider; }
set { dbProvider = value; }
}
public override void Initialize(ITypeLoadHelper loadHelper, ISchedulerSignaler signaler)
{
// Absolutely needs thread-bound DataSource to initialize.
dbProvider = SchedulerFactoryObject.ConfigTimeDbProvider;
if (dbProvider == null)
{
throw new SchedulerConfigException(
"No db provider found for configuration - " +
"'DbProvider' property must be set on SchedulerFactoryObject");
}
// Configure transactional connection settings for Quartz.
DataSource = TX_DATA_SOURCE_PREFIX + InstanceName;
DontSetAutoCommitFalse = true;
// Register transactional ConnectionProvider for Quartz.
DBConnectionManager.Instance.AddConnectionProvider(
TX_DATA_SOURCE_PREFIX + InstanceName, new SpringDbProviderAdapter(dbProvider));
base.Initialize(loadHelper, signaler);
}
protected override ConnectionAndTransactionHolder GetNonManagedTXConnection()
{
return GetConnection();
}
protected override object ExecuteInLock(string lockName, ITransactionCallback txCallback)
{
throw new System.NotImplementedException();
}
protected override void CloseConnection(ConnectionAndTransactionHolder connectionAndTransactionHolder)
{
// Will work for transactional and non-transactional connections.
ConnectionUtils.DisposeConnection(connectionAndTransactionHolder.Connection, dbProvider);
}
}
}

View File

@@ -30,7 +30,10 @@ using Quartz.Xml;
using Spring.Context;
using Spring.Core.IO;
using Spring.Data.Common;
using Spring.Objects.Factory;
using Spring.Transaction;
using Spring.Transaction.Support;
namespace Spring.Scheduling.Quartz
{
@@ -77,8 +80,6 @@ namespace Spring.Scheduling.Quartz
/// <seealso cref="StdSchedulerFactory" />
public class SchedulerFactoryObject : IFactoryObject, IApplicationContextAware, IInitializingObject, IDisposable
{
private const string CONTEXT_KEY_CONFIG_TIME_TASK_EXECUTOR = "sched_factory_conf_t_t_exec";
/// <summary>
/// Default thread count to be set to thread pool.
/// </summary>
@@ -89,6 +90,43 @@ namespace Spring.Scheduling.Quartz
/// </summary>
public const string PROP_THREAD_COUNT = "quartz.threadPool.threadCount";
[ThreadStatic]
private static IDbProvider configTimeDbProvider;
[ThreadStatic]
private static ITaskExecutor configTimeTaskExecutor;
/// <summary>
/// Return the IDbProvider for the currently configured Quartz Scheduler,
/// to be used by LocalDataSourceJobStore.
/// </summary>
/// <remarks>
/// This instance will be set before initialization of the corresponding
/// Scheduler, and reset immediately afterwards. It is thus only available
/// during configuration.
/// </remarks>
/// <seealso cref="DbProvider" />
/// <seealso cref="LocalDataSourceJobStore" />
public static IDbProvider ConfigTimeDbProvider
{
get { return configTimeDbProvider; }
}
/// <summary>
/// Return the TaskExecutor for the currently configured Quartz Scheduler,
/// to be used by LocalTaskExecutorThreadPool.
/// </summary>
/// <remarks>
/// This instance will be set before initialization of the corresponding
/// Scheduler, and reset immediately afterwards. It is thus only available
/// during configuration.
/// </remarks>
public static ITaskExecutor ConfigTimeTaskExecutor
{
get { return configTimeTaskExecutor; }
}
/// <summary>
/// Logger for this instance and its sub-class instances.
/// </summary>
@@ -118,6 +156,8 @@ namespace Spring.Scheduling.Quartz
private ITriggerListener[] triggerListeners;
private ArrayList triggers;
private bool waitForJobsToCompleteOnShutdown;
private IDbProvider dbProvider;
private IPlatformTransactionManager transactionManager;
/// <summary>
/// Initializes a new instance of the <see cref="SchedulerFactoryObject"/> class.
@@ -466,6 +506,42 @@ namespace Spring.Scheduling.Quartz
set { waitForJobsToCompleteOnShutdown = value; }
}
/// <summary>
/// Set the default DbProvider to be used by the Scheduler. If set,
/// this will override corresponding settings in Quartz properties.
/// </summary>
/// <remarks>
/// <p>
/// Note: If this is set, the Quartz settings should not define
/// a job store "dataSource" to avoid meaningless double configuration.
/// </p>
/// <p>
/// A Spring-specific subclass of Quartz' JobStoreSupport will be used.
/// It is therefore strongly recommended to perform all operations on
/// the Scheduler within Spring-managed transactions.
/// Else, database locking will not properly work and might even break
/// (e.g. if trying to obtain a lock on Oracle without a transaction).
/// </p>
/// </remarks>
/// <seealso cref="QuartzProperties" />
/// <seealso cref="TransactionManager" />
/// <seealso cref="LocalDataSourceJobStore" />
public IDbProvider DbProvider
{
set { dbProvider = value; }
}
/// <summary>
/// Set the transaction manager to be used for registering jobs and triggers
/// that are defined by this SchedulerFactoryObject. Default is none; setting
/// this only makes sense when specifying a DataSource for the Scheduler.
/// </summary>
/// <seealso cref="DbProvider" />
public IPlatformTransactionManager TransactionManager
{
set { transactionManager = value; }
}
/// <summary>
/// Gets a value indicating whether this <see cref="SchedulerFactoryObject"/> is running.
/// </summary>
@@ -489,20 +565,6 @@ namespace Spring.Scheduling.Quartz
}
}
/// <summary>
/// Return the TaskExecutor for the currently configured Quartz Scheduler,
/// to be used by LocalTaskExecutorThreadPool.
/// </summary>
/// <remarks>
/// This instance will be set before initialization of the corresponding
/// Scheduler, and reset immediately afterwards. It is thus only available
/// during configuration.
/// </remarks>
public static ITaskExecutor ConfigTimeTaskExecutor
{
get { return (ITaskExecutor) LogicalThreadContext.GetData(CONTEXT_KEY_CONFIG_TIME_TASK_EXECUTOR); }
}
#region IApplicationContextAware Members
/// <summary>
@@ -637,25 +699,51 @@ namespace Spring.Scheduling.Quartz
ISchedulerFactory schedulerFactory = (ISchedulerFactory) ObjectUtils.InstantiateType(schedulerFactoryType);
InitSchedulerFactory(schedulerFactory);
// Get Scheduler instance from SchedulerFactory.
scheduler = CreateScheduler(schedulerFactory, schedulerName);
PopulateSchedulerContext();
if (!jobFactorySet && !(scheduler is RemoteScheduler))
if (taskExecutor != null)
{
// Use AdaptableJobFactory as default for a local Scheduler, unless when
// explicitly given a null value through the "jobFactory" bean property.
jobFactory = new AdaptableJobFactory();
}
if (jobFactory != null)
// Make given TaskExecutor available for SchedulerFactory configuration.
configTimeTaskExecutor = taskExecutor;
}
if (dbProvider != null)
{
if (jobFactory is ISchedulerContextAware)
// Make given db provider available for SchedulerFactory configuration.
configTimeDbProvider = dbProvider;
}
try
{
// Get Scheduler instance from SchedulerFactory.
scheduler = CreateScheduler(schedulerFactory, schedulerName);
PopulateSchedulerContext();
if (!jobFactorySet && !(scheduler is RemoteScheduler))
{
((ISchedulerContextAware) jobFactory).SchedulerContext = scheduler.Context;
// Use AdaptableJobFactory as default for a local Scheduler, unless when
// explicitly given a null value through the "jobFactory" bean property.
jobFactory = new AdaptableJobFactory();
}
if (jobFactory != null)
{
if (jobFactory is ISchedulerContextAware)
{
((ISchedulerContextAware) jobFactory).SchedulerContext = scheduler.Context;
}
scheduler.JobFactory = jobFactory;
}
scheduler.JobFactory = jobFactory;
}
finally
{
if (taskExecutor != null)
{
configTimeTaskExecutor = null;
}
if (dbProvider != null)
{
configTimeDbProvider = null;
}
}
RegisterListeners();
@@ -677,7 +765,7 @@ namespace Spring.Scheduling.Quartz
private void InitSchedulerFactory(ISchedulerFactory schedulerFactory)
{
if (configLocation != null || quartzProperties != null || schedulerName != null ||
taskExecutor != null)
taskExecutor != null || dbProvider != null)
{
if (!(schedulerFactory is StdSchedulerFactory))
{
@@ -726,6 +814,11 @@ namespace Spring.Scheduling.Quartz
MergePropertiesIntoMap(quartzProperties, mergedProps);
}
if (dbProvider != null)
{
mergedProps.Add(StdSchedulerFactory.PropertyJobStoreType, typeof(LocalDataSourceJobStore).FullName);
}
// Make sure to set the scheduler name as configured in the Spring configuration.
if (schedulerName != null)
@@ -845,6 +938,11 @@ namespace Spring.Scheduling.Quartz
/// </summary>
private void RegisterJobsAndTriggers()
{
ITransactionStatus transactionStatus = null;
if (transactionManager != null) {
transactionStatus = transactionManager.GetTransaction(new DefaultTransactionDefinition());
}
try
{
if (jobSchedulingDataLocations != null)
@@ -897,12 +995,30 @@ namespace Spring.Scheduling.Quartz
}
catch (Exception ex)
{
if (transactionStatus != null)
{
try
{
transactionManager.Rollback(transactionStatus);
}
catch (TransactionException)
{
logger.Error("Job registration exception overridden by rollback exception", ex);
throw;
}
}
if (ex is SchedulerException)
{
throw;
}
throw new SchedulerException("Registration of jobs and triggers failed: " + ex.Message, ex);
}
if (transactionStatus != null)
{
transactionManager.Commit(transactionStatus);
}
}
/// <summary>
@@ -1046,5 +1162,6 @@ namespace Spring.Scheduling.Quartz
}
}
}
}
}

View File

@@ -0,0 +1,77 @@
/*
* 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.
*/
using System.Data;
using Quartz.Impl.AdoJobStore;
using Quartz.Impl.AdoJobStore.Common;
namespace Spring.Scheduling.Quartz
{
/// <summary>
/// Adapts Spring's <see cref="Data.Common.IDbProvider"/> to Quartz's
/// <see cref="IDbProvider"/>.
/// </summary>
public class SpringDbProviderAdapter : IDbProvider
{
private readonly Data.Common.IDbProvider dbProvider;
/// <summary>
/// Initializes a new instance of the <see cref="SpringDbProviderAdapter"/> class.
/// </summary>
/// <param name="dbProvider">The Spring db provider.</param>
public SpringDbProviderAdapter(Data.Common.IDbProvider dbProvider)
{
this.dbProvider = dbProvider;
}
public IDbCommand CreateCommand()
{
return dbProvider.CreateCommand();
}
public object CreateCommandBuilder()
{
return dbProvider.CreateCommandBuilder();
}
public IDbConnection CreateConnection()
{
return dbProvider.CreateConnection();
}
public IDbDataParameter CreateParameter()
{
return dbProvider.CreateParameter();
}
public void Shutdown()
{
// no-op
}
public string ConnectionString
{
get { return dbProvider.ConnectionString; }
set { dbProvider.ConnectionString = value; }
}
public DbMetadata Metadata
{
get { throw new System.NotImplementedException(); }
}
}
}

View File

@@ -43,6 +43,7 @@
<HintPath>..\..\..\lib\net\2.0\Quartz.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
</ItemGroup>
<ItemGroup>
<Compile Include="JobMethodInvocationFailedException.cs" />
@@ -54,6 +55,7 @@
<Compile Include="Scheduling\Quartz\ISchedulingTaskExecutor.cs" />
<Compile Include="Scheduling\Quartz\ITaskExecutor.cs" />
<Compile Include="Scheduling\Quartz\JobDetailObject.cs" />
<Compile Include="Scheduling\Quartz\LocalDataSourceJobStore.cs" />
<Compile Include="Scheduling\Quartz\LocalTaskExecutorThreadPool.cs" />
<Compile Include="Scheduling\Quartz\MethodInvokingJob.cs" />
<Compile Include="Scheduling\Quartz\MethodInvokingJobDetailFactoryObject.cs" />
@@ -64,6 +66,7 @@
<Compile Include="Scheduling\Quartz\SchedulingException.cs" />
<Compile Include="Scheduling\Quartz\SimpleThreadPoolTaskExecutor.cs" />
<Compile Include="Scheduling\Quartz\SimpleTriggerObject.cs" />
<Compile Include="Scheduling\Quartz\SpringDbProviderAdapter.cs" />
<Compile Include="Scheduling\Quartz\SpringObjectJobFactory.cs" />
<Compile Include="Scheduling\Quartz\StatefulMethodInvokingJob.cs" />
<Compile Include="Scheduling\Quartz\TaskRejectedException.cs" />
@@ -73,6 +76,10 @@
<Project>{710961A3-0DF4-49E4-A26E-F5B9C044AC84}</Project>
<Name>Spring.Core.2005</Name>
</ProjectReference>
<ProjectReference Include="..\Spring.Data\Spring.Data.2005.csproj">
<Project>{AE00E5AB-C39A-436F-86D2-33BFE33E2E40}</Project>
<Name>Spring.Data.2005</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.