SQL Express 2014 edition call pull Snapshot replication subscribers - replication

I have Sql Stander edition 2014 Which is Distributor and Publisher Also. I created Subscriber on Sql Stander Edition on other Server.Subscriber pull Snapshot Replication is working proper and i can look at the data.
When i Used the 2014 Express edition the pull Subscription is not working because 2014 express edition not support SQL Server Agent.
can any one know any other option is present to call the pull subscription model in the express edition. or we cant do it.
This is Code i have used
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// createSubscriber();
//disableTheServer2Distributor();
}
public bool CreatePublication( string publisherName, string publicationName, string publicationDbName)
{
ReplicationDatabase publicationDb;
TransPublication publication;
// Create a connection to the Publisher using Windows Authentication.
ServerConnection conn;
conn = new ServerConnection(publisherName);
try
{
// Connect to the Publisher.
conn.Connect();
// Enable the AdventureWorks database for transactional publishing.
publicationDb = new ReplicationDatabase(publicationDbName, conn);
// If the database exists and is not already enabled,
// enable it for transactional publishing.
if (publicationDb.LoadProperties())
{
if (!publicationDb.EnabledTransPublishing)
{
publicationDb.EnabledTransPublishing = true;
}
// If the Log Reader Agent does not exist, create it.
if (!publicationDb.LogReaderAgentExists)
{
// Specify the Windows account under which the agent job runs.
// This account will be used for the local connection to the
// Distributor and all agent connections that use Windows Authentication.
publicationDb.LogReaderAgentProcessSecurity.Login = textBox1.Text ;
publicationDb.LogReaderAgentProcessSecurity.Password = textBox2.Text;
// Explicitly set authentication mode for the Publisher connection
// to the default value of Windows Authentication.
publicationDb.LogReaderAgentPublisherSecurity.WindowsAuthentication = true;
// Create the Log Reader Agent job.
publicationDb.CreateLogReaderAgent();
}
}
else
{
throw new ApplicationException(String.Format(
"The {0} database does not exist at {1}.",
publicationDb, publisherName));
}
// Set the required properties for the transactional publication.
publication = new TransPublication();
publication.ConnectionContext = conn;
publication.Name = publicationName;
publication.DatabaseName = publicationDbName;
// Specify a transactional publication (the default).
publication.Type = PublicationType.Snapshot;
// Activate the publication so that we can add subscriptions.
publication.Status = State.Active;
// Enable push and pull subscriptions and independent Distribition Agents.
publication.Attributes |= PublicationAttributes.AllowPull;
//publication.Attributes |= PublicationAttributes.AllowPush;
//publication.Attributes |= PublicationAttributes.IndependentAgent;
// Specify the Windows account under which the Snapshot Agent job runs.
// This account will be used for the local connection to the
// Distributor and all agent connections that use Windows Authentication.
publication.SnapshotGenerationAgentProcessSecurity.Login = textBox1.Text;
publication.SnapshotGenerationAgentProcessSecurity.Password = textBox2.Text;
// Explicitly set the security mode for the Publisher connection
// Windows Authentication (the default).
publication.SnapshotGenerationAgentPublisherSecurity.WindowsAuthentication = true;
ReplicationAgentSchedule schedule;
if (publication.LoadProperties() || publication.SnapshotAvailable)
{
// Set a weekly schedule for the filtered data snapshot.
schedule = new ReplicationAgentSchedule();
schedule.FrequencyType = ScheduleFrequencyType.Continuously;
schedule.FrequencyRecurrenceFactor = 1;
schedule.FrequencyInterval = Convert.ToInt32(0x001);
}
if (!publication.IsExistingObject)
{
// Create the transactional publication.
publication.Create();
// Create a Snapshot Agent job for the publication.
publication.CreateSnapshotAgent();
}
else
{
throw new ApplicationException(String.Format(
"The {0} publication already exists.", publicationName));
}
return true;
}
catch (Exception ex)
{
return false;
// Implement custom application error handling here.
throw new ApplicationException(String.Format(
"The publication {0} could not be created.", publicationName), ex);
}
finally
{
conn.Disconnect();
}
}
/// <summary>
///
/// </summary>
/// <param name="distributionDbName">distribution data base Name</param>
/// <param name="publisherName">Publisher Name </param>
/// <param name="publicationDbName">Publication data base name</param>
/// <param name="distributionDbPassword"> Set the password of the database</param>
/// <param name="WorkingDirectoryPath">Network location from where it can be access </param>
/// <returns></returns>
public bool ConfigurationPublishreAndDistributor(string distributionDbName , string publisherName, string publicationDbName, string distributionDbPassword,string WorkingDirectoryPath)
{
DistributionDatabase distributionDb;
ReplicationServer distributor;
DistributionPublisher publisher;
ReplicationDatabase publicationDb;
// Create a connection to the server using Windows Authentication.
ServerConnection conn = new ServerConnection(publisherName);
try
{
// Connect to the server acting as the Distributor
// and local Publisher.
conn.Connect();
// Define the distribution database at the Distributor,
// but do not create it now.
distributionDb = new DistributionDatabase(distributionDbName, conn);
distributionDb.MaxDistributionRetention = 96;
distributionDb.HistoryRetention = 120;
// Set the Distributor properties and install the Distributor.
// This also creates the specified distribution database.
distributor = new ReplicationServer(conn);
distributor.InstallDistributor(distributionDbPassword, distributionDb);
// Set the Publisher properties and install the Publisher.
publisher = new DistributionPublisher(publisherName, conn);
publisher.DistributionDatabase = distributionDb.Name;
publisher.WorkingDirectory = WorkingDirectoryPath;
publisher.PublisherSecurity.WindowsAuthentication = true;
publisher.Create();
// Enable AdventureWorks2012 as a publication database.
publicationDb = new ReplicationDatabase(publicationDbName, conn);
publicationDb.EnabledTransPublishing = true;
publicationDb.EnabledMergePublishing = true;
return true;
}
catch (Exception ex)
{
// Implement appropriate error handling here.
return false;
throw new ApplicationException("An error occured when installing distribution and publishing.", ex);
}
finally
{
conn.Disconnect();
}
}
private void CreateDistributorServer1_Click(object sender, EventArgs e)
{
if (ConfigurationPublishreAndDistributor("distribution", #"SERVER-002\SQLSERVER2014", "ReplicationDB", "Asdf1234!", #"\\SERVER-001\Replication-001"))
{
if (CreatePublication(#"SERVER-002\SQLSERVER2014", "ReplicationSnapShort", "ReplicationDB"))
{
string publisherName = #"SERVER-002\SQLSERVER2014";
string publicationName = "ReplicationSnapShort";
string publicationDbName = "ReplicationDB";
string articleName = "student";
string schemaOwner = "dbo";
TransArticle article;
// Create a connection to the Publisher.
ServerConnection conn = new ServerConnection(publisherName);
// Create a filtered transactional articles in the following steps:
// 1) Create the article with a horizontal filter clause.
// 2) Add columns to or remove columns from the article.
try
{
// Connect to the Publisher.
conn.Connect();
// Define a horizontally filtered, log-based table article.
article = new TransArticle();
article.ConnectionContext = conn;
article.Name = articleName;
article.DatabaseName = publicationDbName;
article.SourceObjectName = articleName;
article.SourceObjectOwner = schemaOwner;
article.PublicationName = publicationName;
article.Type = ArticleOptions.LogBased;
String[] articlecolumns = new String[2];
articlecolumns[0] = "studentid";
articlecolumns[1] = "name";
article.AddReplicatedColumns(articlecolumns);
//article.FilterClause = "DiscontinuedDate IS NULL";
// Ensure that we create the schema owner at the Subscriber.
article.SchemaOption |= CreationScriptOptions.Schema;
if (!article.IsExistingObject)
{
// Create the article.
article.Create();
}
else
{
throw new ApplicationException(String.Format(
"The article {0} already exists in publication {1}.",
articleName, publicationName));
}
// Create an array of column names to remove from the article.
String[] columns = new String[2];
columns[0] = "studentid";
columns[1] = "name";
// Remove the column from the article.
article.AddReplicatedColumns(columns);
// publication.StartSnapshotGenerationAgentJob();
}
catch (Exception ex)
{
// Implement appropriate error handling here.
throw new ApplicationException("The article could not be created.", ex);
}
finally
{
conn.Disconnect();
startTheAgentNow();
}
}
}
MessageBox.Show("Create the Distributor and Publisher");
}
public bool startTheAgentNow()
{
string publisherName = #"SERVER-002\SQLSERVER2014";
string publicationName = "ReplicationSnapShort";
string publicationDbName = "ReplicationDB";
TransPublication publication;
// Create a connection to the Publisher using Windows Authentication.
ServerConnection conn;
conn = new ServerConnection(publisherName);
try
{
// Connect to the Publisher.
conn.Connect();
// Set the required properties for an existing publication.
publication = new TransPublication();
publication.ConnectionContext = conn;
publication.Name = publicationName;
publication.DatabaseName = publicationDbName;
if (publication.LoadProperties())
{
// Start the Snapshot Agent job for the publication.
publication.StartSnapshotGenerationAgentJob();
}
else
{
throw new ApplicationException(String.Format(
"The {0} publication does not exist.", publicationName));
}
}
catch (Exception ex)
{
// Implement custom application error handling here.
throw new ApplicationException(String.Format(
"A snapshot could not be generated for the {0} publication."
, publicationName), ex);
}
finally
{
conn.Disconnect();
// createSubscriber();
}
return true;
}
public bool createSubscriber()
{
// Define the Publisher, publication, and databases.
string publicationName = "ReplicationSnapShort";
string publisherName = #"SERVER-002\SQLSERVER2014";
string subscriberName = #"SERVER-001\SQLSERVER2014";
string subscriptionDbName = "ReplicationDB1";
string publicationDbName = "ReplicationDB";
//Create connections to the Publisher and Subscriber.
ServerConnection subscriberConn = new ServerConnection(subscriberName);
ServerConnection publisherConn = new ServerConnection(publisherName);
// Create the objects that we need.
TransPublication publication;
TransPullSubscription subscription;
try
{
// Connect to the Publisher and Subscriber.
subscriberConn.Connect();
publisherConn.Connect();
// Ensure that the publication exists and that
// it supports pull subscriptions.
publication = new TransPublication();
publication.Name = publicationName;
publication.DatabaseName = publicationDbName;
publication.ConnectionContext = publisherConn;
if (publication.IsExistingObject)
{
if ((publication.Attributes & PublicationAttributes.AllowPull) == 0)
{
publication.Attributes |= PublicationAttributes.AllowPull;
}
// Define the pull subscription.
subscription = new TransPullSubscription();
subscription.ConnectionContext = subscriberConn;
subscription.PublisherName = publisherName;
subscription.PublicationName = publicationName;
subscription.PublicationDBName = publicationDbName;
subscription.DatabaseName = subscriptionDbName;
// Specify the Windows login credentials for the Distribution Agent job.
subscription.SynchronizationAgentProcessSecurity.Login = textBox1.Text;
subscription.SynchronizationAgentProcessSecurity.Password = textBox2.Text;
// Make sure that the agent job for the subscription is created.
subscription.CreateSyncAgentByDefault = true;
// By default, subscriptions to transactional publications are synchronized
// continuously, but in this case we only want to synchronize on demand.
subscription.AgentSchedule.FrequencyType = ScheduleFrequencyType.Continuously;
// Create the pull subscription at the Subscriber.
subscription.Create();
Boolean registered = false;
// Verify that the subscription is not already registered.
foreach (TransSubscription existing
in publication.EnumSubscriptions())
{
if (existing.SubscriberName == subscriberName
&& existing.SubscriptionDBName == subscriptionDbName)
{
registered = true;
}
}
if (!registered)
{
// Register the subscription with the Publisher.
publication.MakePullSubscriptionWellKnown(
subscriberName, subscriptionDbName,
SubscriptionSyncType.Automatic,
TransSubscriberType.ReadOnly);
}
}
else
{
// Do something here if the publication does not exist.
throw new ApplicationException(String.Format(
"The publication '{0}' does not exist on {1}.",
publicationName, publisherName));
}
}
catch (Exception ex)
{
// Implement the appropriate error handling here.
throw new ApplicationException(String.Format(
"The subscription to {0} could not be created.", publicationName), ex);
}
finally
{
subscriberConn.Disconnect();
publisherConn.Disconnect();
}
MessageBox.Show("Subscription is Created");
return true;
}
/// <summary>
/// This is the code of the
/// </summary>
public void disableTheServer2Distributor()
{
string publisherName = #"SERVER-002\SQLSERVER2014";
string publicationDbName = "ReplicationDB";
string distributorName = #"SERVER-002\SQLSERVER2014";
string distributionDbName = "distribution";
// Create connections to the Publisher and Distributor
// using Windows Authentication.
ServerConnection publisherConn = new ServerConnection(publisherName);
ServerConnection distributorConn = new ServerConnection(distributorName);
// Create the objects we need.
ReplicationServer distributor =
new ReplicationServer(distributorConn);
DistributionPublisher publisher;
DistributionDatabase distributionDb =
new DistributionDatabase(distributionDbName, distributorConn);
ReplicationDatabase publicationDb;
publicationDb = new ReplicationDatabase(publicationDbName, publisherConn);
try
{
// Connect to the Publisher and Distributor.
publisherConn.Connect();
distributorConn.Connect();
// Disable all publishing on the AdventureWorks2012 database.
if (publicationDb.LoadProperties())
{
if (publicationDb.EnabledMergePublishing)
{
publicationDb.EnabledMergePublishing = false;
}
else if (publicationDb.EnabledTransPublishing)
{
publicationDb.EnabledTransPublishing = false;
}
}
else
{
throw new ApplicationException(
String.Format("The {0} database does not exist.", publicationDbName));
}
// We cannot uninstall the Publisher if there are still Subscribers.
if (distributor.RegisteredSubscribers.Count == 0)
{
// Uninstall the Publisher, if it exists.
publisher = new DistributionPublisher(publisherName, distributorConn);
if (publisher.LoadProperties())
{
publisher.Remove(false);
}
else
{
// Do something here if the Publisher does not exist.
throw new ApplicationException(String.Format(
"{0} is not a Publisher for {1}.", publisherName, distributorName));
}
// Drop the distribution database.
if (distributionDb.LoadProperties())
{
distributionDb.Remove();
}
else
{
// Do something here if the distribition DB does not exist.
throw new ApplicationException(String.Format(
"The distribution database '{0}' does not exist on {1}.",
distributionDbName, distributorName));
}
// Uninstall the Distributor, if it exists.
if (distributor.LoadProperties())
{
// Passing a value of false means that the Publisher
// and distribution databases must already be uninstalled,
// and that no local databases be enabled for publishing.
distributor.UninstallDistributor(false);
}
else
{
//Do something here if the distributor does not exist.
throw new ApplicationException(String.Format(
"The Distributor '{0}' does not exist.", distributorName));
}
}
else
{
throw new ApplicationException("You must first delete all subscriptions.");
}
}
catch (Exception ex)
{
// Implement appropriate error handling here.
throw new ApplicationException("The Publisher and Distributor could not be uninstalled", ex);
}
finally
{
publisherConn.Disconnect();
distributorConn.Disconnect();
}
}
private void CreateDistributorServer2_Click(object sender, EventArgs e)
{
}
private void button5_Click(object sender, EventArgs e)
{
createSubscriber();
}
private void button13_Click(object sender, EventArgs e)
{
string publisherName = #"SERVER-002\SQLSERVER2014";
string publicationDbName = "ReplicationDB";
String subscriberName = #"SERVER-001\SQLSERVER2014";
String publicationName = "ReplicationSnapShort";
String subscriptionDbName = "ReplicationDB1";
// Create a connection to the Subscriber.
ServerConnection conn = new ServerConnection(subscriberName);
TransPullSubscription subscription;
try
{
// Connect to the Subscriber.
conn.Connect();
// Define subscription properties.
subscription = new TransPullSubscription();
subscription.ConnectionContext = conn;
subscription.DatabaseName = subscriptionDbName;
subscription.PublisherName = publisherName;
subscription.PublicationDBName = publicationDbName;
subscription.PublicationName = publicationName;
// If the pull subscription and the job exists, mark the subscription
// for reinitialization and start the agent job.
if (subscription.LoadProperties() && subscription.AgentJobId != null)
{
subscription.Reinitialize();
subscription.SynchronizeWithJob();
}
else
{
// Do something here if the subscription does not exist.
throw new ApplicationException(String.Format(
"A subscription to '{0}' does not exists on {1}",
publicationName, subscriberName));
}
}
catch (Exception ex)
{
// Do appropriate error handling here.
//throw new ApplicationException("The subscription could not be reinitialized.", ex);
}
finally
{
conn.Disconnect();
startTheAgentNow();
MessageBox.Show("Agents are started");
}
}
private void button9_Click(object sender, EventArgs e)
{
}
}
Above Code is Working as Expected I getting issue When I change the Subscriber to SQL

I see you are using the TransPullSubscription class and calling the SynchronizeWithJob() method to synchronize the subscription. As you found out, the SQL Server Agent is not available in SQL Server Express so this approach does not work.
However, the RMO TransSynchronizationAgent class exposes a Synchronize method which can be used to synchronize a pull subscription without an agent job. This is covered in How to: Synchronize a Pull Subscription (RMO Programming).
Get an instance of the TransSynchronizationAgent class from the
SynchronizationAgent property, and call the Synchronize method. This
method starts the agent synchronously, and control remains with the
running agent job. During synchronous execution, you can handle the
Status event while the agent is running.
I have a similar example for a Merge pull subscription found here.
Note that if you specified a value of false for CreateSyncAgentByDefault (the default) when you created the pull subscription, you also need to set additional properties before you can call Synchronize().
If you specified a value of false for CreateSyncAgentByDefault (the
default) when you created the pull subscription, you also need to
specify Distributor, DistributorSecurityMode, and optionally
DistributorLogin and DistributorPassword because the agent job related
metadata for the subscription is not available in
MSsubscription_properties.

Thanks
Brandon Williams ,
I make the changes on the code is given below
`
{
TransSynchronizationAgent agent;
// Sync BackgroundWorker
BackgroundWorker syncBackgroundWorker;
public Form1()
{
InitializeComponent();
lblSubscriptionName.Text = "[" + subscriptionDbName + "] - [" + publisherName + "] - [" + publicationDbName + "]";
lblPublicationName.Text = publicationName;
}
private void btnStart_Click(object sender, EventArgs e)
{
// Instantiate a BackgroundWorker, subscribe to its events, and call RunWorkerAsync()
syncBackgroundWorker = new BackgroundWorker();
syncBackgroundWorker.WorkerReportsProgress = true;
syncBackgroundWorker.DoWork += new DoWorkEventHandler(syncBackgroundWorker_DoWork);
syncBackgroundWorker.ProgressChanged += new ProgressChangedEventHandler(syncBackgroundWorker_ProgressChanged);
syncBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(syncBackgroundWorker_RunWorkerCompleted);
// Disable the start button
btnStart.Enabled = false;
// Initialize the progress bar and status textbox
pbStatus.Value = 0;
tbLastStatusMessage.Text = String.Empty;
pictureBoxStatus.Visible = true;
pictureBoxStatus.Enabled = true;
// Kick off a background operation to synchronize
syncBackgroundWorker.RunWorkerAsync();
}
// This event handler initiates the synchronization
private void syncBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
// Connect to the Subscriber and synchronize
SynchronizeMergePullSubscriptionViaRMO();
}
// Synchronize
public void SynchronizeMergePullSubscriptionViaRMO()
{
// Create a connection to the Subscriber.
ServerConnection conn = new ServerConnection(subscriberName);
// Merge pull subscription
TransPullSubscription subscription;
try
{
// Connect to the Subscriber.
conn.Connect();
// Define the pull subscription.
subscription = new TransPullSubscription();
subscription.ConnectionContext = conn;
subscription.DatabaseName = subscriptionDbName;
subscription.PublisherName = publisherName;
subscription.PublicationDBName = publicationDbName;
subscription.PublicationName = publicationName;
// If the pull subscription exists, then start the synchronization.
if (subscription.LoadProperties())
{
// Get the agent for the subscription.
agent = subscription.SynchronizationAgent;
// Set the required properties that could not be returned
// from the MSsubscription_properties table.
//agent.PublisherSecurityMode = SecurityMode.Integrated;
agent.DistributorSecurityMode = SecurityMode.Integrated;
agent.Distributor = publisherName;
// Enable verbose merge agent output to file.
agent.OutputVerboseLevel = 4;
agent.Output = "C:\\TEMP\\mergeagent.log";
// Handle the Status event
agent.Status += new AgentCore.StatusEventHandler(agent_Status);
// Synchronously start the Merge Agent for the subscription.
agent.Synchronize();
}
else
{
// Do something here if the pull subscription does not exist.
throw new ApplicationException(String.Format(
"A subscription to '{0}' does not exist on {1}",
publicationName, subscriberName));
}
}
catch (Exception ex)
{
// Implement appropriate error handling here.
throw new ApplicationException("The subscription could not be " +
"synchronized. Verify that the subscription has " +
"been defined correctly.", ex);
}
finally
{
conn.Disconnect();
}
}
// This event handler handles the Status event and reports the agent progress.
public void agent_Status(object sender, StatusEventArgs e)
{
syncBackgroundWorker.ReportProgress(Convert.ToInt32(e.PercentCompleted), e.Message.ToString());
}
// This event handler updates the form with agent progress.
private void syncBackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// Set the progress bar percent completed
pbStatus.Value = e.ProgressPercentage;
// Append the last agent message
tbLastStatusMessage.Text += e.UserState.ToString() + Environment.NewLine;
// Scroll to end
ScrollToEnd();
}
// This event handler deals with the results of the background operation.
private void syncBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled == true)
{
tbLastStatusMessage.Text += "Canceled!" + Environment.NewLine;
ScrollToEnd();
}
else if (e.Error != null)
{
tbLastStatusMessage.Text += "Error: " + e.Error.Message + Environment.NewLine;
ScrollToEnd();
}
else
{
tbLastStatusMessage.Text += "Done!" + Environment.NewLine;
ScrollToEnd();
}
btnStart.Enabled = true;
pictureBoxStatus.Enabled = false;
}
private void ScrollToEnd()
{
// Scroll to end
tbLastStatusMessage.SelectionStart = tbLastStatusMessage.TextLength;
tbLastStatusMessage.ScrollToCaret();
}
private void btnClose_Click(object sender, EventArgs e)
{
this.Close();
}
}`

Related

Sql Dependency - Notification received before processing current request

I am currently using sql dependency notification to detect changes in a table and process them. I am having a problem where the notification gets called while its still in the middle of completing the first request which causes duplicate processing
private void ProcessData()
{
try
{
m_Guids = new List<Guid>();
using (SqlCommand command = new SqlCommand("SP_XXX_SELECT", m_sqlConn))
{
command.CommandType = CommandType.StoredProcedure;
command.Notification = null;
SqlDependency dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(OnDependencyChange);
SqlDependency.Start(m_ConnectionString, m_QueueName);
if (m_sqlConn.State == ConnectionState.Closed)
{
m_sqlConn.Open();
}
using (SqlDataReader reader = command.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
m_Guids.Add(reader.GetGuid(0));
}
}
}
Console.WriteLine(m_Guids.Count.ToString());
ProcessGuids();
}
}
}
catch (Exception ex)
{
//SendFailureEmail
}
}
private void OnDependencyChange(object sender, SqlNotificationEventArgs e)
{
SqlDependency dependency = sender as SqlDependency;
dependency.OnChange -= OnDependencyChange;
ProcessData();
}
public void OnStart()
{
SqlDependency.Stop(m_ConnectionString, m_QueueName);
SqlDependency.Start(m_ConnectionString, m_QueueName);
m_sqlConn = new SqlConnection(m_ConnectionString);
}
ProcessData method gets called again while its still in the middle of processing (processGuids) Should I subscribe to the event after processing all the data?
If I don't subscribe until processing is complete, what happens to the data that was changed during the process, which I believe doesn't get notified until next change happens?. What is the correct way of doing this or am I doing something wrong.
Thanks
SqlDependency.OnChange is called not only on data change.
In the OnDependencyChange you must check e.Type/e.Source/e.Info.
F.e., combination of {Type = Subscribe, Source = Statement, Info = Invalid} means "Statement not ready for notification, no notification started".
See Creating a Query for Notification for SQL statement requirements for notification. You must follow these requirements in SELECT statements in your SP.
Additional requirements for stored procedures are not well documented. Known restrictions for SP:
Use of SET NOCOUNT (ON and OFF) is prohibited.
Use of RETURN is prohibited.

activemq delete consumed messages

I am using ActiveMQ in my app. My question is how to delete messages that ı consumed successfully from kahadb. Because if it is not deleted, my db.data file is growing up constantly.
Here is my consumer;
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:8182");
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue("TEST.FOO");
MessageConsumer consumer = session.createConsumer(destination);
MessageListener listner = new MessageListener() {
int count = 0;
public void onMessage(Message message) {
if (message instanceof ObjectMessage) {
ObjectMessage objectMessage = (ObjectMessage) message;
ResponseDuration responseDuration = null;
try {
responseDuration = (ResponseDuration) objectMessage.getObject();
System.out.println("Received Time : " + new Date() + "Received: " + responseDuration.toString());
} catch (JMSException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
ResponseDurationOperations.insertResponseDurations(responseDuration);
count++;
System.out.println("Count = " + count);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
consumer.setMessageListener(listner);
Seems that ActiveMQ has a different meaning for what it means with persistance than you (and me as well).
Persistence is defined not to persist for ever but just to make you safe from message loss when you restart the server. See this
One option for you could be to switch off the persistence. See here.
For example by this way:
ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");

JGroups not forming a cluster with UDP

I am trying to create a leader election protocol using JGroups so that N instances of my program can elect a master and all clients get the ip of this master.
More or less the current implementation relies on each instance trying to acquire a lock on lock-channel and when it successfully acquires this channel it becomes master and all others switch to clients.
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.*;
import org.jgroups.*;
import org.jgroups.blocks.locking.LockService;
public class AutoDiscovery
{
static org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(AutoDiscovery.class); //used for logging purposes (see log4j library)
/* this variable indicates whether I have become the master or I'm just a client*/
public volatile AtomicBoolean becomeMaster = new AtomicBoolean(false);
/* The address of the server if we are a client or of ourself if we are
* server */
public String serverAddress;
/* A channel on which to acquire a lock, so that only one can become server */
private JChannel lockChannel;
/* A shared channel ffor communication between client and master*/
private JChannel communicationChannel;
private LockService lockService;
/* A thread which tries to acquire a lock */
private Thread acquiringThread;
/* A thread which listens for the server ip which may change */
private Thread listeningThread;
/* A thread which lists the status and initializes the acquiring thread*/
private Thread statusThread;
private String name;
/* If we pass from being a client to being a server we must stop the listening
* thread however we cannot call listeningThread.stop() but instead we change
* the stopListening boolean to true */
private boolean stopListening = false;
/* This lock communicates I have finally become either master or client so
* the serverAddress and becomeMaster variables are correctly set */
public final Object finishedLock = new Object();
public static void main(String[] args) throws Exception
{
Thread.currentThread().setName("MyMainThread");
Random rand = new Random();
AutoDiscovery master = new AutoDiscovery("Node" + rand.nextInt(10));
master.lockChannel = new JChannel(AutoDiscovery.class.getResource("/resource/udp.xml"));
master.lockChannel.connect("lock-channel");
master.communicationChannel = new JChannel(AutoDiscovery.class.getResource("/resource/udp.xml"));
master.communicationChannel.connect("communication-channel");
master.lockService = new LockService(master.lockChannel);
master.startStatusPrinterThread();
}
public AutoDiscovery(String name)
{
this.name = name;
}
public AutoDiscovery()
{
try
{
Thread.currentThread().setName("MyMainThread");
Random rand = new Random();
this.name = ("Node" + rand.nextInt(10));
lockChannel = new JChannel(AutoDiscovery.class.getResource("/resource/udp.xml"));
lockChannel.connect("lock-channel");
communicationChannel = new JChannel(AutoDiscovery.class.getResource("/resource/udp.xml"));
communicationChannel.connect("communication-channel");
lockService = new LockService(lockChannel);
startStatusPrinterThread();
}
catch (Exception ex)
{
Logger.getLogger(AutoDiscovery.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void startAcquiringThread()
{
acquiringThread = new Thread()
{
#Override
public void run()
{
while (true)
{
//if you have become Master send your ip every now and then
if (becomeMaster.get())
{
try
{
communicationChannel.send(new Message(null, null, "serverip " + serverAddress));
}
catch (Exception ex)
{
Logger.getLogger(AutoDiscovery.class.getName()).log(Level.SEVERE, null, ex);
}
}
else
{
try
{
Thread.currentThread().setName(name + "AcquiringThread");
Lock lock = lockService.getLock("serverLock");
if (lock.tryLock(4, TimeUnit.SECONDS))
{
becomeMaster.set(true);
stopListening = true;
/* Now that I'm server I must find out my own ip address on which to listen */
Enumeration<NetworkInterface> networkInterfaces;
try
{
networkInterfaces = NetworkInterface.getNetworkInterfaces();
for (NetworkInterface netint : Collections.list(networkInterfaces))
{
Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
for (InetAddress inetAddress : Collections.list(inetAddresses))
{
if (isIPAddress(inetAddress.getHostAddress())
&& !inetAddress.getHostAddress().equals("127.0.0.1"))
{
serverAddress = inetAddress.getHostAddress();
}
}
}
/* I notify to the rest of the program I have correctly initialized
* becomeMaster and serverAddress */
synchronized (finishedLock)
{
finishedLock.notify();
}
}
catch (Exception e)
{
Logger.getLogger(AutoDiscovery.class.getName()).log(Level.SEVERE, null, e);
System.exit(0);
}
log.info(Thread.currentThread().getName() + ": I acquired lock! will become master! my ip is " + serverAddress);
}
else
{
becomeMaster.set(false);
stopListening = false;
if (listeningThread == null || !listeningThread.isAlive())
{
if (!stopListening) //??? this codnition might be useless
{
startListeningThread();
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
try
{
sleep(5000L);
}
catch (InterruptedException ex)
{
Logger.getLogger(AutoDiscovery.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
};
acquiringThread.setDaemon(true);
acquiringThread.start();
}
public void startListeningThread()
{
listeningThread = new Thread()
{
#Override
public void run()
{
try
{
while (true)
{
Thread.currentThread().setName(name + "ListeningThread");
communicationChannel.setReceiver(new ReceiverAdapter()
{
#Override
public void receive(Message msg)
{
if (msg.getObject() != null)
{
String leaderServerAddress = (msg.getObject().toString().substring(9));
if (isIPAddress(leaderServerAddress))
{
serverAddress = leaderServerAddress;
log.info(name + " Master server has ip" + serverAddress);
/* I notify to the rest of the program I have correctly initialized
* becomeMaster and serverAddress */
synchronized (finishedLock)
{
finishedLock.notify();
}
}
else
{
log.info(name + ": discarded message " + msg.getObject().toString());
}
}
}
});
sleep(10000L);
if (stopListening)
{
return;
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
};
listeningThread.setDaemon(true);
listeningThread.start();
}
private void startStatusPrinterThread()
{
statusThread = new Thread()
{
#Override
public void run()
{
Thread.currentThread().setName(name + "StatusPrinterThread");
startAcquiringThread();
while (true)
{
try
{
if (becomeMaster.get())
{
log.info(name + " startStatusPrinterThread(): I am happily a Master!");
}
else
{
if (!acquiringThread.isAlive())
{
startAcquiringThread();
}
}
sleep(5000L);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
};
statusThread.setDaemon(true);
statusThread.start();
}
private static boolean isIPAddress(String str)
{
Pattern ipPattern = Pattern.compile("^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
+ "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
+ "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
+ "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$");
return ipPattern.matcher(str).matches();
}
}
now my current udp.xml is
<config xmlns="urn:org:jgroups"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:org:jgroups http://www.jgroups.org/schema/JGroups-3.0.xsd">
<UDP
mcast_port="${jgroups.udp.mcast_port:45588}"
tos="8"
ucast_recv_buf_size="20M"
ucast_send_buf_size="640K"
mcast_recv_buf_size="25M"
mcast_send_buf_size="640K"
loopback="true"
level="WARN"
log_discard_msgs="false"
max_bundle_size="64K"
max_bundle_timeout="30"
ip_ttl="${jgroups.udp.ip_ttl:8}"
enable_diagnostics="true"
thread_naming_pattern="cl"
timer_type="new"
timer.min_threads="4"
timer.max_threads="10"
timer.keep_alive_time="3000"
timer.queue_max_size="500"
thread_pool.enabled="true"
thread_pool.min_threads="2"
thread_pool.max_threads="8"
thread_pool.keep_alive_time="5000"
thread_pool.queue_enabled="true"
thread_pool.queue_max_size="10000"
thread_pool.rejection_policy="discard"
oob_thread_pool.enabled="true"
oob_thread_pool.min_threads="1"
oob_thread_pool.max_threads="8"
oob_thread_pool.keep_alive_time="5000"
oob_thread_pool.queue_enabled="false"
oob_thread_pool.queue_max_size="100"
oob_thread_pool.rejection_policy="Run"/>
<PING timeout="2000"
num_initial_members="3"/>
<MERGE2 max_interval="30000"
min_interval="10000"/>
<FD_SOCK/>
<FD_ALL/>
<VERIFY_SUSPECT timeout="1500" />
<BARRIER />
<pbcast.NAKACK exponential_backoff="300"
xmit_stagger_timeout="200"
use_mcast_xmit="false"
discard_delivered_msgs="true"/>
<UNICAST />
<pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000"
max_bytes="4M"/>
<pbcast.GMS print_local_addr="true" join_timeout="3000"
view_bundling="true"/>
<UFC max_credits="2M"
min_threshold="0.4"/>
<MFC max_credits="2M"
min_threshold="0.4"/>
<FRAG2 frag_size="60K" />
<pbcast.STATE_TRANSFER />
<CENTRAL_LOCK />
<!-- pbcast.FLUSH /-->
</config>
Now the above works when I run N instances of the program on the same machine (with N-1 members becoming client and 1 becoming master).
When run on two different machines both connected to the same LAN, apparently after calling JChannel.connect() with the same clustername in each member, each member creates its channel and no common cluster is created. The result is that when sending messages to the clients the other master sees a different physical address for the same cluster name and all messages are dropped.
So I get warnings like:
7683 [Incoming-1,communication-channel,pc-home-41714] WARN org.jgroups.protocols.pbcast.NAKACK - [JGRP00011] pc-home-41714: dropped message 293 from non-member cf8b4ea6-8cc8-cb21-538f-b03f3fa7413d (view=[pc-home-41714|0] [pc-home-41714])
1207996 [TransferQueueBundler,communication-channel,pc-home-5280] WARN org.jgroups.protocols.UDP - pc-home-5280: no physical address for cf8b4ea6-8cc8-cb21-538f-b03f3fa7413d, dropping message
1209526 [TransferQueueBundler,lock-channel,pc-home-59082] WARN org.jgroups.protocols.UDP - pc-home-59082: no physical address for efbe6408-0e21-d119-e2b8-f1d5762d9b45, dropping message
If I change udp.xml loopback="true" to loopback="false" what happens is that they both connect to the same cluster but then they give an error like:
55539 [Node0StatusPrinterThread] INFO plarz.net.planningig.autodiscovery.AutoDiscovery - Node0 startStatusPrinterThread(): I am happily a Master!
59077 [TransferQueueBundler,lock-channel,pc-test-6919] ERROR org.jgroups.protocols.UDP - pc-test-6919: exception sending bundled msgs: java.lang.Exception: dest=/fe80:0:0:0:226:18ff:fece:6ccc%2:43109 (130 bytes):, cause: java.io.IOException: Network is unreachable
59505 [TransferQueueBundler,communication-channel,pc-test-35303] ERROR org.jgroups.protocols.UDP - pc-test-35303: exception sending bundled msgs: java.lang.Exception: dest=/fe80:0:0:0:226:18ff:fece:6ccc%2:55053 (139 bytes):, cause: java.io.IOException: Network is unreachable
Error:
[Server:ha-server-3] 13:59:13,122 WARNING [org.jgroups.protocols.UDP]
(OOB-15,null) null: no physical address for
766de5c9-8ac2-6d30-89ef-78d39aa5f7eb, dropping message
In My case, it was due to having multiple jboss clusters at a same
network and each of the clusters were having same name. For example
ha-server-1 and ha-server-2 existed at two different clusters in
different machines.
Cluster-1(10.10.10.10): |
+- ha-server-1
+- ha-server-2
Cluster-2(10.10.10.20): |
+- ha-server-1
+- ha-server-2
I have resolved this problem by changing the ha-server names. Note:
Both were independent cluster. I assume it happened due to the
multicast issue of JGroups. Any further explanation from an expert
like you will be nice.
refer to http://icfun.blogspot.com/2013/10/no-physical-address-for-766de5c9-8ac2.html

Sharepoint 2010 Web Part Communication - How to make consumer wait for the provider

I have a series of web parts I need to implement in SharePoint 2010. The data provider web part uses an UpdatePanel and asynchronously makes a web service call which can potentially be slow. To keep it simple, I've put a single consumer web part on the page (Chart) which will use the consumer as its data provider.
My problem is that I can't get the consumer to wait for the provider - I get a variety of errors but all basically come back to "There is no data available". This may be because it is a Chart web part but the question also applies to the other custom parts I will be developing as they will pull the same data.
The question is: how do I either push data to my consumers when my provider is ready or somehow let them wait for my provider to have data (via polling or whatever).
Note: this is just a prototype, I haven't added error handling, etc yet.
Code is below:
[ToolboxItem(true)]
public partial class ClarityProjectGeneral : System.Web.UI.WebControls.WebParts.WebPart , IWebPartTable
{
public DataTable ProjectVitals = new DataTable(); For web part communication
// bunch of properties
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
InitializeControl();
// For web part communication
// Initialize our datatable so the chart doesn't barf
DataColumn col = new DataColumn();
col.DataType = typeof(string);
col.ColumnName = "Name";
this.ProjectVitals.Columns.Add(col);
col = new DataColumn();
col.DataType = typeof(DateTime);
col.ColumnName = "Start";
this.ProjectVitals.Columns.Add(col);
col = new DataColumn();
col.DataType = typeof(DateTime);
col.ColumnName = "End";
this.ProjectVitals.Columns.Add(col);
}
protected void Page_Load(object sender, EventArgs e)
{
loading.Visible = true;
content.Visible = false;
}
public ClarityObjectClasses.Projects GetProject(string projectID)
{
Clarity.ClarityAbstractorProject ca = new Clarity.ClarityAbstractorProject(this.Username, this.Password);
Dictionary<string, string> queryParams = new Dictionary<string, string>();
queryParams.Add("projectID", projectID);
// Class for making web service call
ClarityObjectClasses.Projects response = new ClarityObjectClasses.Projects();
response = ca.GetProject(queryParams);
return response;
}
protected void Timer1_Tick(object sender, EventArgs e)
{
if (this.ProjectID == null || this.Username == null || this.Password == null)
{
lblConfigError.Visible = true;
lblConfigError.Text = "One or more required configuration values are not set. Please check the web part configuration.";
panelProjectDetails.Visible = false;
}
else
{
loading.Visible = true;
content.Visible = false;
panelProjectDetails.Visible = true;
ClarityObjectClasses.Projects projects = GetProject(this.ProjectID);
//Assign a bunch of values
// For web part communication
LoadTable(projects.Project[0]);
Timer1.Enabled = false;
loading.Visible = false;
content.Visible = true;
}
}
/* Interface functions for Graph Chart communication */
For web part communication
protected void LoadTable(ClarityObjectClasses.Project project)
{
DataRow row = ProjectVitals.NewRow();
row["Name"] = project.name;
row["Start"] = project.start;
row["End"] = project.finish;
this.ProjectVitals.Rows.Add(row);
}
public PropertyDescriptorCollection Schema
{
get
{
return TypeDescriptor.GetProperties(ProjectVitals.DefaultView[0]);
}
}
public void GetTableData(TableCallback callback)
{
callback(ProjectVitals.Rows);
}
public bool ConnectionPointEnabled
{
get
{
object o = ViewState["ConnectionPointEnabled"];
return (o != null) ? (bool)o : true;
}
set
{
ViewState["ConnectionPointEnabled"] = value;
}
}
[ConnectionProvider("Table", typeof(TableProviderConnectionPoint), AllowsMultipleConnections = true)]
public IWebPartTable GetConnectionInterface()
{
return this;
}
public class TableProviderConnectionPoint : ProviderConnectionPoint
{
public TableProviderConnectionPoint(MethodInfo callbackMethod, Type interfaceType, Type controlType, string name, string id, bool allowsMultipleConnections)
: base(callbackMethod, interfaceType, controlType, name, id, allowsMultipleConnections)
{
}
public override bool GetEnabled(Control control)
{
return ((ClarityProjectGeneral)control).ConnectionPointEnabled;
}
}
}
Do not quite understand, but if it helps
You may not use "connectable" web-parts inside UpdatePanel,
because of lack of corresponding events to bind data on asynchronous callback.
I just stumbled across this. I had exactly the same problem trying to implement a custom webpart just as a proof to myself. I applied filters to both my webpart and a list, and then let a chart consume them. What I found was that my webpart sent the wrong data, but the list webpart worked as expected.
So I reflected the XsltListViewWebPart (or whatever it's exact name is) and I discovered that there is an IConnectionData interface. This allows you to specify the dependencies and get the correct delay binding you need. GetRequiresData indicates that there are still more connections to be consumed before the data can be requested.

Duplex WCF + Static Collection of COM objects

I am trying to build a WCF service that exposes the functionality of a particular COM object that I do not have the original source for. I am using duplex binding so that each client has their own instance as there are events tied to each particular instance which are delivered through a callback (IAgent). It appears there is a deadlock or something because after the first action, my service blocks at my second action's lock. I have tried implementing these custom STA attribute and operation behaviors (http://devlicio.us/blogs/scott_seely/archive/2009/07/17/calling-an-sta-com-object-from-a-wcf-operation.aspx) but my OperationContext.Current is always null. Any advice is much appreciated.
Service
Collection:
private static Dictionary<IAgent, COMAgent> agents = new Dictionary<IAgent, COMAgent>();
First action:
public void Login(LoginRequest request)
{
IAgent agent = OperationContext.Current.GetCallbackChannel<IAgent>();
lock (agents)
{
if (agents.ContainsKey(agent))
throw new FaultException("You are already logged in.");
else
{
ICOMClass startup = new ICOMClass();
string server = ConfigurationManager.AppSettings["Server"];
int port = Convert.ToInt32(ConfigurationManager.AppSettings["Port"]);
bool success = startup.Logon(server, port, request.Username, request.Password);
if (!success)
throw new FaultException<COMFault>(new COMFault { ErrorText = "Could not log in." });
COMAgent comAgent = new COMAgent { Connection = startup };
comAgent.SomeEvent += new EventHandler<COMEventArgs>(comAgent_COMEvent);
agents.Add(agent, comAgent);
}
}
}
Second Action:
public void Logoff()
{
IAgent agent = OperationContext.Current.GetCallbackChannel<IAgent>();
lock (agents)
{
COMAgent comAgent = agents[agent];
try
{
bool success = comAgent.Connection.Logoff();
if (!success)
throw new FaultException<COMFault>(new COMFault { ErrorText = "Could not log off." });
agents.Remove(agent);
}
catch (Exception exc)
{
throw new FaultException(exc.Message);
}
}
}
Take a look at this very similar post: http://www.netfxharmonics.com/2009/07/Accessing-WPF-Generated-Images-Via-WCF
You have to use an OperationContextScope to have access to the current OperationContext from the newly generated thread:
System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(delegate
{
using (System.ServiceModel.OperationContextScope scope = new System.ServiceModel.OperationContextScope(context))
{
result = InnerOperationInvoker.Invoke(instance, inputs, out staOutputs);
}
}));