Discussion:
SqlDependency and Updates
(too old to reply)
Florian
2006-01-11 09:46:02 UTC
Permalink
Hello,

I've got a little trouble because updates seem to trigger SqlDependencies
even if the update is already finished.

I'm watching data with an SqlDependency which I eventually update myself.
When I update the data I do it like this:

- Release current SqlDependency
- Update Data
- Read data again to aquire a new SqlDependency

Shortly after acquiring the new SqlDependency it fires its change event for
the preceding update statement.
When debugging or calling Thread.Sleep(1000) right after the update
everything works fine - it's as if the Update is comitted with a slight delay
like file IO where you have to use Flush if you *really* want to have the
data on disk and not in some cache which is still waiting to have enough data
to issue a real disk-write.

Does anyone know of a better way than working with some made-up delay -
which for all I know might even vary depending on the servers performance?

Thanks,

Florian
Niels Berglund
2006-01-11 15:26:04 UTC
Permalink
Post by Florian
I've got a little trouble because updates seem to trigger
SqlDependencies even if the update is already finished.
I don't understand what you mean with this. Isn't the idea that an
update should fire the dependency?
Post by Florian
I'm watching data with an SqlDependency which I eventually update
- Release current SqlDependency
- Update Data
- Read data again to aquire a new SqlDependency
Shortly after acquiring the new SqlDependency it fires its change
event for the preceding update statement.
You are releasing the dependency - what do you mean with that? It'd help
if you could post a sample scenario which shows the behavior you are
talking about.

Niels
--
**************************************************
* Niels Berglund
* http://staff.develop.com/nielsb
* ***@no-spam.develop.com
* "A First Look at SQL Server 2005 for Developers"
* http://www.awprofessional.com/title/0321180593
**************************************************
Florian
2006-01-11 16:17:02 UTC
Permalink
Hi Niels,

thanks for your answer!
Post by Niels Berglund
Post by Florian
I've got a little trouble because updates seem to trigger
SqlDependencies even if the update is already finished.
I don't understand what you mean with this. Isn't the idea that an
update should fire the dependency?
Well, yes, but not if I initiate the Trigger *after* the update.
Post by Niels Berglund
Post by Florian
I'm watching data with an SqlDependency which I eventually update
- Release current SqlDependency
- Update Data
- Read data again to aquire a new SqlDependency
Shortly after acquiring the new SqlDependency it fires its change
event for the preceding update statement.
You are releasing the dependency - what do you mean with that? It'd help
if you could post a sample scenario which shows the behavior you are
talking about.
Below I've pasted a quick example to reproduce it. I've used a Form with two
buttons, clicking Button1 will insert a new row and afterwards call a Select
on the table with an attached SqlDependency.

When you click Button2(without the Thread.Sleep) you will receive the
changed event - right *after* the update, which is exactly my problem(or at
least it's what I experience in my environment). You can click Button2
repeatedly which simulates more or less what my Program does.
If you put the Thread.Sleep in it's allright, though.
And it's not due to the ExecNonQuery because originally I'm using a
TableAdapter which doesn't use ExecNonQuery afaik.

Thanks so far,

Florian


Table Structure:
CREATE TABLE [dbo].[Table1](
[ID] [uniqueidentifier] NOT NULL CONSTRAINT [DF_Table1_ID] DEFAULT
(newid()),
[name] [nvarchar](50) COLLATE Latin1_General_CI_AS NULL,
CONSTRAINT [PK_Table1] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Data.SqlClient;

namespace SqlDependencyUpdateBugSample
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

//variables
private const string CONSTRING = "Data Source=local;Initial
Catalog=Test;User ID=sa";
private Guid guid;
private DataSet1 ds = new DataSet1();
private SqlDependency dep = null;

private void button1_Click(object sender, EventArgs e)
{
//get a connection
SqlConnection con = new SqlConnection(CONSTRING);
con.Open();

//insert a new row
guid = Guid.NewGuid();
SqlCommand cmd = new SqlCommand("INSERT INTO Table1 VALUES ('" +
guid.ToString() + "', 'Hello World')", con);
cmd.ExecuteNonQuery();

//do a select on the table
cmd.CommandText = "SELECT ID, name FROM dbo.Table1";
//with an assigned SqlDependency
this.dep = new SqlDependency(cmd);
this.dep.OnChange += new OnChangeEventHandler(dep_OnChange);
cmd.ExecuteNonQuery();
con.Close();
}

void dep_OnChange(object sender, SqlNotificationEventArgs e)
{
MessageBox.Show("Changed");
}

private void button2_Click(object sender, EventArgs e)
{
//"release" dependency
this.dep.OnChange -= new OnChangeEventHandler(dep_OnChange);
this.dep = null;

SqlConnection con = new SqlConnection(CONSTRING);
con.Open();

//update the row - at this point we won't get any notifications
because the old dep is gone
SqlCommand cmd = new SqlCommand("UPDATE Table1 SET
name='Testing...' WHERE ID = '" + guid.ToString() + "'", con);
cmd.ExecuteNonQuery();

//System.Threading.Thread.Sleep(1000); //sleep a little so the
update can get through

//re-acquire the SqlDependency
//without the Thread.Sleep this dependency object will fire
shortly after the Execute which
cmd.CommandText = "SELECT ID, name FROM dbo.Table1";
this.dep = new SqlDependency(cmd);
this.dep.OnChange += new OnChangeEventHandler(dep_OnChange);
cmd.ExecuteNonQuery();
con.Close();
}

private void Form1_Load(object sender, EventArgs e)
{
SqlDependency.Start(CONSTRING);
}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
SqlDependency.Stop(CONSTRING);
}
}
}
Niels Berglund
2006-01-11 19:35:26 UTC
Permalink
Post by Florian
Hi Niels,
thanks for your answer!
Post by Niels Berglund
Post by Florian
I've got a little trouble because updates seem to trigger
SqlDependencies even if the update is already finished.
I don't understand what you mean with this. Isn't the idea that an
update should fire the dependency?
Well, yes, but not if I initiate the Trigger *after* the update.
Post by Niels Berglund
Post by Florian
I'm watching data with an SqlDependency which I eventually update
- Release current SqlDependency
- Update Data
- Read data again to aquire a new SqlDependency
Shortly after acquiring the new SqlDependency it fires its change
event for the preceding update statement.
You are releasing the dependency - what do you mean with that? It'd
help if you could post a sample scenario which shows the behavior you
are talking about.
Hmm, interesting - I can repro what you are seeing. I need to look into
this in a little more detail to figure out what is going on.

Niels
--
**************************************************
* Niels Berglund
* http://staff.develop.com/nielsb
* ***@no-spam.develop.com
* "A First Look at SQL Server 2005 for Developers"
* http://www.awprofessional.com/title/0321180593
**************************************************
Florian
2006-01-12 16:43:04 UTC
Permalink
Post by Niels Berglund
Hmm, interesting - I can repro what you are seeing. I need to look into
this in a little more detail to figure out what is going on.
Niels
Well, that's a start - at least it's not my own fault ;)

I would be grateful for any help, otherwise I'll have to do with Thread.Sleep.
If I find some better solution I'll let you know.

Florian

Continue reading on narkive:
Search results for 'SqlDependency and Updates' (Questions and Answers)
4
replies
how can i make my own instant messenger?
started 2008-07-13 09:51:47 UTC
programming & design
Loading...