Showing posts with label concurrency. Show all posts
Showing posts with label concurrency. Show all posts

Friday, February 17, 2012

Concurrency?

How do you handle this today?
I am mapping out a new system and was interested in a fresh approach.
__Stephen
That's a big topic. In SQL Server 2005, concurrency has been enhanced with
snapshot isolation, as well as database snapshots. With older versions, you
can use dirty reads, optimistic locking and READPAST.
Tom
Thomas A. Moreau, BSc, PhD, MCSE, MCDBA
SQL Server MVP
Columnist, SQL Server Professional
Toronto, ON Canada tom@.cips.ca
www.pinpub.com
"__Stephen" <srussell@.transactiongraphics.com> wrote in message
news:esteMwm%23FHA.924@.TK2MSFTNGP12.phx.gbl...
> How do you handle this today?
> I am mapping out a new system and was interested in a fresh approach.
> __Stephen
>
|||Is there a specific problem you're having? Why aren't SQL Server's built-in
facilities for handling concurrency good for your situation?
Adam Machanic
Pro SQL Server 2005, available now
http://www.apress.com/book/bookDisplay.html?bID=457
"__Stephen" <srussell@.transactiongraphics.com> wrote in message
news:esteMwm%23FHA.924@.TK2MSFTNGP12.phx.gbl...
> How do you handle this today?
> I am mapping out a new system and was interested in a fresh approach.
> __Stephen
>
|||"Adam Machanic" <amachanic@.hotmail._removetoemail_.com> wrote in message
news:uSTN9Bn%23FHA.2520@.TK2MSFTNGP15.phx.gbl...
> Is there a specific problem you're having? Why aren't SQL Server's
> built-in facilities for handling concurrency good for your situation?
>
What I have is the statement created in my biz layer and presented back to
the db with an "and" stipulation.
update
MyTable
set myChangedColumn = NewValue , ..
where Pkey = ThisKey
AND myChangedColumn = OldValue , ..
Thus I'm only changing what the user has changed, and it won't whack someone
elses update who also changed the same value.
Is there a better way to do this?
My GUI is ASP or ASP.NET and mostly ASP today
__Stephen
|||"Tom Moreau" <tom@.dont.spam.me.cips.ca> wrote in message
news:OvmQ4Bn%23FHA.4012@.TK2MSFTNGP10.phx.gbl...
> snapshot isolation, as well as database snapshots. With older versions,
> you can use dirty reads, optimistic locking and READPAST.
Do you mean, "pessimistic" locking?
Adam Machanic
Pro SQL Server 2005, available now
http://www.apress.com/book/bookDisplay.html?bID=457
|||Nope, optimistic. Optimistic locking allows you to release the lock right
after you read it. Then, when you go to update it, if the timestamps
(rowversions) don't match, then you can retrieve the current version. That
provides more concurrency than when you keep the row locked until the user
has finished their update.
Tom
Thomas A. Moreau, BSc, PhD, MCSE, MCDBA
SQL Server MVP
Columnist, SQL Server Professional
Toronto, ON Canada tom@.cips.ca
www.pinpub.com
"Adam Machanic" <amachanic@.hotmail._removetoemail_.com> wrote in message
news:%23sN69Kn%23FHA.328@.TK2MSFTNGP14.phx.gbl...
> "Tom Moreau" <tom@.dont.spam.me.cips.ca> wrote in message
> news:OvmQ4Bn%23FHA.4012@.TK2MSFTNGP10.phx.gbl...
> Do you mean, "pessimistic" locking?
>
> --
> Adam Machanic
> Pro SQL Server 2005, available now
> http://www.apress.com/book/bookDisplay.html?bID=457
> --
>
|||"__Stephen" <srussell@.transactiongraphics.com> wrote in message
news:u2re6Jn%23FHA.1028@.TK2MSFTNGP11.phx.gbl...
> "Adam Machanic" <amachanic@.hotmail._removetoemail_.com> wrote in message
> news:uSTN9Bn%23FHA.2520@.TK2MSFTNGP15.phx.gbl...
> What I have is the statement created in my biz layer and presented back to
> the db with an "and" stipulation.
> update
> MyTable
> set myChangedColumn = NewValue , ..
> where Pkey = ThisKey
> AND myChangedColumn = OldValue , ..
> Thus I'm only changing what the user has changed, and it won't whack
> someone elses update who also changed the same value.
> Is there a better way to do this?
>
You can add a timestamp column to the table to simply the stipulation, but
basically you've got it right. It's not generally practical to use
pessimistic concurrency from clients like ASP.NET, so client-generated
optimistic concurrency is the norm.
David
|||"Tom Moreau" <tom@.dont.spam.me.cips.ca> wrote in message
news:%23eeN1Nn%23FHA.2520@.TK2MSFTNGP15.phx.gbl...
> Nope, optimistic. Optimistic locking allows you to release the lock right
> after you read it. Then, when you go to update it, if the timestamps
> (rowversions) don't match, then you can retrieve the current version.
> That provides more concurrency than when you keep the row locked until the
> user has finished their update.
Right, but the important point is, SQL Server 2000's isolation levels are
all pessimistic. Applications can implement an optimistic scheme -- but
this is the application doing so, not SQL Server.
Adam Machanic
Pro SQL Server 2005, available now
http://www.apress.com/book/bookDisplay.html?bID=457
|||Right. I was assuming he was asking for ideas on how to minimize
concurrency problems.
Tom
Thomas A. Moreau, BSc, PhD, MCSE, MCDBA
SQL Server MVP
Columnist, SQL Server Professional
Toronto, ON Canada tom@.cips.ca
www.pinpub.com
"Adam Machanic" <amachanic@.hotmail._removetoemail_.com> wrote in message
news:O$6XNao%23FHA.3296@.TK2MSFTNGP10.phx.gbl...
> "Tom Moreau" <tom@.dont.spam.me.cips.ca> wrote in message
> news:%23eeN1Nn%23FHA.2520@.TK2MSFTNGP15.phx.gbl...
> Right, but the important point is, SQL Server 2000's isolation levels are
> all pessimistic. Applications can implement an optimistic scheme -- but
> this is the application doing so, not SQL Server.
>
> --
> Adam Machanic
> Pro SQL Server 2005, available now
> http://www.apress.com/book/bookDisplay.html?bID=457
> --
>

Concurrency?

How do you handle this today?
I am mapping out a new system and was interested in a fresh approach.
__StephenThat's a big topic. In SQL Server 2005, concurrency has been enhanced with
snapshot isolation, as well as database snapshots. With older versions, you
can use dirty reads, optimistic locking and READPAST.
Tom
----
Thomas A. Moreau, BSc, PhD, MCSE, MCDBA
SQL Server MVP
Columnist, SQL Server Professional
Toronto, ON Canada tom@.cips.ca
www.pinpub.com
"__Stephen" <srussell@.transactiongraphics.com> wrote in message
news:esteMwm%23FHA.924@.TK2MSFTNGP12.phx.gbl...
> How do you handle this today?
> I am mapping out a new system and was interested in a fresh approach.
> __Stephen
>|||Is there a specific problem you're having? Why aren't SQL Server's built-in
facilities for handling concurrency good for your situation?
Adam Machanic
Pro SQL Server 2005, available now
http://www.apress.com/book/bookDisplay.html?bID=457
--
"__Stephen" <srussell@.transactiongraphics.com> wrote in message
news:esteMwm%23FHA.924@.TK2MSFTNGP12.phx.gbl...
> How do you handle this today?
> I am mapping out a new system and was interested in a fresh approach.
> __Stephen
>|||"Adam Machanic" <amachanic@.hotmail._removetoemail_.com> wrote in message
news:uSTN9Bn%23FHA.2520@.TK2MSFTNGP15.phx.gbl...
> Is there a specific problem you're having? Why aren't SQL Server's
> built-in facilities for handling concurrency good for your situation?
>
What I have is the statement created in my biz layer and presented back to
the db with an "and" stipulation.
update
MyTable
set myChangedColumn = NewValue , ..
where Pkey = ThisKey
AND myChangedColumn = OldValue , ..
Thus I'm only changing what the user has changed, and it won't whack someone
elses update who also changed the same value.
Is there a better way to do this?
My GUI is ASP or ASP.NET and mostly ASP today
__Stephen|||"Tom Moreau" <tom@.dont.spam.me.cips.ca> wrote in message
news:OvmQ4Bn%23FHA.4012@.TK2MSFTNGP10.phx.gbl...
> snapshot isolation, as well as database snapshots. With older versions,
> you can use dirty reads, optimistic locking and READPAST.
Do you mean, "pessimistic" locking?
Adam Machanic
Pro SQL Server 2005, available now
http://www.apress.com/book/bookDisplay.html?bID=457
--|||Nope, optimistic. Optimistic locking allows you to release the lock right
after you read it. Then, when you go to update it, if the timestamps
(rowversions) don't match, then you can retrieve the current version. That
provides more concurrency than when you keep the row locked until the user
has finished their update.
Tom
----
Thomas A. Moreau, BSc, PhD, MCSE, MCDBA
SQL Server MVP
Columnist, SQL Server Professional
Toronto, ON Canada tom@.cips.ca
www.pinpub.com
"Adam Machanic" <amachanic@.hotmail._removetoemail_.com> wrote in message
news:%23sN69Kn%23FHA.328@.TK2MSFTNGP14.phx.gbl...
> "Tom Moreau" <tom@.dont.spam.me.cips.ca> wrote in message
> news:OvmQ4Bn%23FHA.4012@.TK2MSFTNGP10.phx.gbl...
> Do you mean, "pessimistic" locking?
>
> --
> Adam Machanic
> Pro SQL Server 2005, available now
> http://www.apress.com/book/bookDisplay.html?bID=457
> --
>|||"__Stephen" <srussell@.transactiongraphics.com> wrote in message
news:u2re6Jn%23FHA.1028@.TK2MSFTNGP11.phx.gbl...
> "Adam Machanic" <amachanic@.hotmail._removetoemail_.com> wrote in message
> news:uSTN9Bn%23FHA.2520@.TK2MSFTNGP15.phx.gbl...
> What I have is the statement created in my biz layer and presented back to
> the db with an "and" stipulation.
> update
> MyTable
> set myChangedColumn = NewValue , ..
> where Pkey = ThisKey
> AND myChangedColumn = OldValue , ..
> Thus I'm only changing what the user has changed, and it won't whack
> someone elses update who also changed the same value.
> Is there a better way to do this?
>
You can add a timestamp column to the table to simply the stipulation, but
basically you've got it right. It's not generally practical to use
pessimistic concurrency from clients like ASP.NET, so client-generated
optimistic concurrency is the norm.
David|||"Tom Moreau" <tom@.dont.spam.me.cips.ca> wrote in message
news:%23eeN1Nn%23FHA.2520@.TK2MSFTNGP15.phx.gbl...
> Nope, optimistic. Optimistic locking allows you to release the lock right
> after you read it. Then, when you go to update it, if the timestamps
> (rowversions) don't match, then you can retrieve the current version.
> That provides more concurrency than when you keep the row locked until the
> user has finished their update.
Right, but the important point is, SQL Server 2000's isolation levels are
all pessimistic. Applications can implement an optimistic scheme -- but
this is the application doing so, not SQL Server.
Adam Machanic
Pro SQL Server 2005, available now
http://www.apress.com/book/bookDisplay.html?bID=457
--|||Right. I was assuming he was asking for ideas on how to minimize
concurrency problems.
Tom
----
Thomas A. Moreau, BSc, PhD, MCSE, MCDBA
SQL Server MVP
Columnist, SQL Server Professional
Toronto, ON Canada tom@.cips.ca
www.pinpub.com
"Adam Machanic" <amachanic@.hotmail._removetoemail_.com> wrote in message
news:O$6XNao%23FHA.3296@.TK2MSFTNGP10.phx.gbl...
> "Tom Moreau" <tom@.dont.spam.me.cips.ca> wrote in message
> news:%23eeN1Nn%23FHA.2520@.TK2MSFTNGP15.phx.gbl...
> Right, but the important point is, SQL Server 2000's isolation levels are
> all pessimistic. Applications can implement an optimistic scheme -- but
> this is the application doing so, not SQL Server.
>
> --
> Adam Machanic
> Pro SQL Server 2005, available now
> http://www.apress.com/book/bookDisplay.html?bID=457
> --
>

Concurrency?

How do you handle this today?
I am mapping out a new system and was interested in a fresh approach.
__StephenThat's a big topic. In SQL Server 2005, concurrency has been enhanced with
snapshot isolation, as well as database snapshots. With older versions, you
can use dirty reads, optimistic locking and READPAST.
--
Tom
----
Thomas A. Moreau, BSc, PhD, MCSE, MCDBA
SQL Server MVP
Columnist, SQL Server Professional
Toronto, ON Canada tom@.cips.ca
www.pinpub.com
"__Stephen" <srussell@.transactiongraphics.com> wrote in message
news:esteMwm%23FHA.924@.TK2MSFTNGP12.phx.gbl...
> How do you handle this today?
> I am mapping out a new system and was interested in a fresh approach.
> __Stephen
>|||Is there a specific problem you're having? Why aren't SQL Server's built-in
facilities for handling concurrency good for your situation?
Adam Machanic
Pro SQL Server 2005, available now
http://www.apress.com/book/bookDisplay.html?bID=457
--
"__Stephen" <srussell@.transactiongraphics.com> wrote in message
news:esteMwm%23FHA.924@.TK2MSFTNGP12.phx.gbl...
> How do you handle this today?
> I am mapping out a new system and was interested in a fresh approach.
> __Stephen
>|||"Adam Machanic" <amachanic@.hotmail._removetoemail_.com> wrote in message
news:uSTN9Bn%23FHA.2520@.TK2MSFTNGP15.phx.gbl...
> Is there a specific problem you're having? Why aren't SQL Server's
> built-in facilities for handling concurrency good for your situation?
>
What I have is the statement created in my biz layer and presented back to
the db with an "and" stipulation.
update
MyTable
set myChangedColumn = NewValue , ..
where Pkey = ThisKey
AND myChangedColumn = OldValue , ..
Thus I'm only changing what the user has changed, and it won't whack someone
elses update who also changed the same value.
Is there a better way to do this?
My GUI is ASP or ASP.NET and mostly ASP today :(
__Stephen|||"Tom Moreau" <tom@.dont.spam.me.cips.ca> wrote in message
news:OvmQ4Bn%23FHA.4012@.TK2MSFTNGP10.phx.gbl...
> snapshot isolation, as well as database snapshots. With older versions,
> you can use dirty reads, optimistic locking and READPAST.
Do you mean, "pessimistic" locking?
Adam Machanic
Pro SQL Server 2005, available now
http://www.apress.com/book/bookDisplay.html?bID=457
--|||Nope, optimistic. Optimistic locking allows you to release the lock right
after you read it. Then, when you go to update it, if the timestamps
(rowversions) don't match, then you can retrieve the current version. That
provides more concurrency than when you keep the row locked until the user
has finished their update.
--
Tom
----
Thomas A. Moreau, BSc, PhD, MCSE, MCDBA
SQL Server MVP
Columnist, SQL Server Professional
Toronto, ON Canada tom@.cips.ca
www.pinpub.com
"Adam Machanic" <amachanic@.hotmail._removetoemail_.com> wrote in message
news:%23sN69Kn%23FHA.328@.TK2MSFTNGP14.phx.gbl...
> "Tom Moreau" <tom@.dont.spam.me.cips.ca> wrote in message
> news:OvmQ4Bn%23FHA.4012@.TK2MSFTNGP10.phx.gbl...
>> snapshot isolation, as well as database snapshots. With older versions,
>> you can use dirty reads, optimistic locking and READPAST.
> Do you mean, "pessimistic" locking?
>
> --
> Adam Machanic
> Pro SQL Server 2005, available now
> http://www.apress.com/book/bookDisplay.html?bID=457
> --
>|||"__Stephen" <srussell@.transactiongraphics.com> wrote in message
news:u2re6Jn%23FHA.1028@.TK2MSFTNGP11.phx.gbl...
> "Adam Machanic" <amachanic@.hotmail._removetoemail_.com> wrote in message
> news:uSTN9Bn%23FHA.2520@.TK2MSFTNGP15.phx.gbl...
>> Is there a specific problem you're having? Why aren't SQL Server's
>> built-in facilities for handling concurrency good for your situation?
> What I have is the statement created in my biz layer and presented back to
> the db with an "and" stipulation.
> update
> MyTable
> set myChangedColumn = NewValue , ..
> where Pkey = ThisKey
> AND myChangedColumn = OldValue , ..
> Thus I'm only changing what the user has changed, and it won't whack
> someone elses update who also changed the same value.
> Is there a better way to do this?
>
You can add a timestamp column to the table to simply the stipulation, but
basically you've got it right. It's not generally practical to use
pessimistic concurrency from clients like ASP.NET, so client-generated
optimistic concurrency is the norm.
David|||"Tom Moreau" <tom@.dont.spam.me.cips.ca> wrote in message
news:%23eeN1Nn%23FHA.2520@.TK2MSFTNGP15.phx.gbl...
> Nope, optimistic. Optimistic locking allows you to release the lock right
> after you read it. Then, when you go to update it, if the timestamps
> (rowversions) don't match, then you can retrieve the current version.
> That provides more concurrency than when you keep the row locked until the
> user has finished their update.
Right, but the important point is, SQL Server 2000's isolation levels are
all pessimistic. Applications can implement an optimistic scheme -- but
this is the application doing so, not SQL Server.
Adam Machanic
Pro SQL Server 2005, available now
http://www.apress.com/book/bookDisplay.html?bID=457
--|||Right. I was assuming he was asking for ideas on how to minimize
concurrency problems.
--
Tom
----
Thomas A. Moreau, BSc, PhD, MCSE, MCDBA
SQL Server MVP
Columnist, SQL Server Professional
Toronto, ON Canada tom@.cips.ca
www.pinpub.com
"Adam Machanic" <amachanic@.hotmail._removetoemail_.com> wrote in message
news:O$6XNao%23FHA.3296@.TK2MSFTNGP10.phx.gbl...
> "Tom Moreau" <tom@.dont.spam.me.cips.ca> wrote in message
> news:%23eeN1Nn%23FHA.2520@.TK2MSFTNGP15.phx.gbl...
>> Nope, optimistic. Optimistic locking allows you to release the lock
>> right after you read it. Then, when you go to update it, if the
>> timestamps (rowversions) don't match, then you can retrieve the current
>> version. That provides more concurrency than when you keep the row locked
>> until the user has finished their update.
> Right, but the important point is, SQL Server 2000's isolation levels are
> all pessimistic. Applications can implement an optimistic scheme -- but
> this is the application doing so, not SQL Server.
>
> --
> Adam Machanic
> Pro SQL Server 2005, available now
> http://www.apress.com/book/bookDisplay.html?bID=457
> --
>

Concurrency, have I got this more or less right?

Following on from a thread I started about "concurrency" (real-time-ish
system), I thought I would play about to see if I could easily adapt my data
model to take account of potential multi-user write conflicts. So, I would
appreciate you checking my logic/reasoning to see if this kind of thing
will work. Below I have a stored procedure that will simply delete a given
record from a given table. I have appended a "_Written" counter to the
columns of the table. Every time the record is written, the counter is
incremented. Clients store the current _Written count in their objects and
pass this in to any write procedure executed.

The procedure explicitly checks the _Written count within the transaction to
see if it agress with the written count passed in by the client. If it does
not, the client throws an error. Note I am explicitly checking the
_Written count precisely so I can determine exactly why this operation might
fail, rather than checking @.@.ROWCOUNT after an update.

Thanks.

Robin

CREATE PROCEDURE dbo.proc_DS_Remove_DataSet

@._In_ID INTEGER,
@._In_Written INTEGER

AS

DECLARE @.Error INTEGER
DECLARE @.WRITTEN INTEGER

BEGIN TRANSACTION
SET @.Error = @.@.ERROR

IF @.Error = 0
BEGIN

SELECT @.WRITTEN = _Written FROM MyTable WHERE ID = @._In_ID
SET @.Error = @.@.ERROR

IF @.WRITTEN <> @._In_Written
BEGIN
RAISERROR ('10', 16, 1)
SET @.Error = @.@.ERROR
END

END

IF @.Error = 0
BEGIN
DELETE FROM MyTable WHERE ID = @._In_ID
SET @.Error = @.@.ERROR
END

IF @.Error = 0
COMMIT TRANSACTION
ELSE
ROLLBACK TRANSACTION

RETURN @.ErrorYou can use binary_checksum to check for changes without having to
append an extra field onto every table. If any field in the row
changes, the checksum will change.|||On Fri, 21 Jan 2005 13:36:12 -0000, Robin Tucker wrote:

> I would
>appreciate you checking my logic/reasoning to see if this kind of thing
>will work.
(snip)

Hi Robin,

It will work, but some remarks nonetheless.

1. Consider using a timestamp column instead of your _Written column. SQL
Server will automaticall update the value of the timestamp column whenever
the row is inserted or updated; you never have to include it in your code.
But you can use it to check that the row is untouched the same way you
propose to do it with your self-made _Written column.
(Note: despite the name, the timestamp value is in no way related to date
or time of latest update. The synonym for timestamp is rowversion, which
describes the actual function of this datatype lots better)

2. Even if you check that _Written (or the timestamp column) is unchanged
before doing the delete, I'd recommend you to still include
WHERE _Written = @.WRITTEN
in the actual delete statement. There's always the theoretical possibility
that someone updates the row in the split microsecond between the SELECT
and the DELETE.
An alternative to this is to set the transaction isolation level to
REPEATABLE READ or to use the HOLDLOCK locking hint on the select. This
ensures that the lock used to read the row is not released after the read
operation, but retained until the transaction is finished, precluding any
changes from other connections to the row.

Best, Hugo
--

(Remove _NO_ and _SPAM_ to get my e-mail address)|||Robin Tucker (idontwanttobespammedanymore@.reallyidont.com) writes:
> CREATE PROCEDURE dbo.proc_DS_Remove_DataSet
> @._In_ID INTEGER,
> @._In_Written INTEGER
> AS
> DECLARE @.Error INTEGER
> DECLARE @.WRITTEN INTEGER
> BEGIN TRANSACTION
> SET @.Error = @.@.ERROR
> IF @.Error = 0
> BEGIN
> SELECT @.WRITTEN = _Written FROM MyTable WHERE ID = @._In_ID
> SET @.Error = @.@.ERROR

You should have "WITH (UPDLOCK)" after MyTable where. This is a shared
lock, so the row is still readable for others. But no other can get a
second UPDLOCK. This prevents other process from coming inbetween and
modifying the row.

Hugo suggested HOLDLOCK, but HOLDLOCK is a read-only lock. If two
processes attacks the same row simultaneously, you will get a deadlock,
because both get their HOLDLOCK, and none can delete because of the
other.

Using timestamps that Hugo suggested is an excellent idea.

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp|||On Fri, 21 Jan 2005 22:53:20 +0000 (UTC), Erland Sommarskog wrote:

>You should have "WITH (UPDLOCK)"
(snip)
>Hugo suggested HOLDLOCK, but HOLDLOCK is a read-only lock.

Oops! You're right - I just keep interchanging these two.

Thanks for the correction, Erland!

Best, Hugo
--

(Remove _NO_ and _SPAM_ to get my e-mail address)|||Thanks both of you for your replies. Somewhere I missed the "timestamp"
type and yes that would be more suitable. Also will read up on locking
semantics as I was under the impression everything within my transaction
would be applied with the given rows locked for updates any way.

Thanks.

"Hugo Kornelis" <hugo@.pe_NO_rFact.in_SPAM_fo> wrote in message
news:p623v0hig394jkmboq5n476pecd8bmbs2j@.4ax.com...
> On Fri, 21 Jan 2005 22:53:20 +0000 (UTC), Erland Sommarskog wrote:
>>You should have "WITH (UPDLOCK)"
> (snip)
>>Hugo suggested HOLDLOCK, but HOLDLOCK is a read-only lock.
> Oops! You're right - I just keep interchanging these two.
> Thanks for the correction, Erland!
> Best, Hugo
> --
> (Remove _NO_ and _SPAM_ to get my e-mail address)

Concurrency violation error!

Hi
im keep getting the following error
Concurrency violation: the UpdateCommand affected 0 records

I dunno whats wrong, im the only person using the database and program at the moment.
Anyone know what im doing wrong?

thanks

Can you post your problematic code here?

Concurrency violation adding records Why?

Hi,
I'm getting periodic concurrency violations while adding new records, can
someone please tell me how to resolve this. I have an application that is
running multi-user, approx 60+ users and for some reason my application is
throwing a concurrency violation when adding a new record, I have a
bindingsource that is bound to several fields, I then issue a EndEdit()
followed by an update. 95% of the time it works and the other 5% I get a
concurrency error.. This is very frustrating. the dataset being updated
contains an identity field which is an int, I set this identity field using
the datasets autoincrement feature and autostep -1. My insert statement
does NOT contain the identity field.
Thanks,If your clustered index column is going down by 1 (increment set to negative
one) then you do realize that SQL Server has to reorganize the entire table
after every single insert? If this is the case it might be at least
contributing to/exacerbating your issue.
"Rob Dob" <robdob20012002@.yahoo.com> wrote in message
news:%23qbtuTJKIHA.3516@.TK2MSFTNGP02.phx.gbl...
> Hi,
> I'm getting periodic concurrency violations while adding new records, can
> someone please tell me how to resolve this. I have an application that
> is running multi-user, approx 60+ users and for some reason my application
> is throwing a concurrency violation when adding a new record, I have a
> bindingsource that is bound to several fields, I then issue a EndEdit()
> followed by an update. 95% of the time it works and the other 5% I get a
> concurrency error.. This is very frustrating. the dataset being updated
> contains an identity field which is an int, I set this identity field
> using the datasets autoincrement feature and autostep -1. My insert
> statement does NOT contain the identity field.
>
> Thanks,
>|||the identity column never makes it to the sql, its only their to satisfy my
datatset. when the update method of my tableadapter is called it has no
mention of the identity column.
Do you have any other ideas? thank you for your help.
"Mike C#" <xyz@.xyz.com> wrote in messa ge
news:%234qPSXKKIHA.5468@.TK2MSFTNGP05.phx.gbl...
> If your clustered index column is going down by 1 (increment set to
> negative one) then you do realize that SQL Server has to reorganize the
> entire table after every single insert? If this is the case it might be
> at least contributing to/exacerbating your issue.
> "Rob Dob" <robdob20012002@.yahoo.com> wrote in message
> news:%23qbtuTJKIHA.3516@.TK2MSFTNGP02.phx.gbl...
>|||I'm going to make several assumptions.
1) You use identity keys in the database.
2) You have figured out how to get the keys back to replace negative keys in
your dataset that existed prior to update.
3) You are using timestamps for concurrency (that's a big assumption).
4) You process the dataset updates in chunks using the
dataset.GetChanges(Deleted | Modified | Added)
5) You process the deletes first up the hierarchy. Then, you process the
adds down the parent chain. Finally, you process the modifies.
Let's say the user modified the parent row and added new child rows.
Here is what I discovered. Dataset.GetChanges(DataRowState.Added) gets the
added rows as you would expect. It also includes any modified parents. If
you do a DataAdapter.Update(dsAdded.table), it will insert the new child
rows AND will also update the parent row if it had been modified. Fine so
far. Here is what happens next. You do the
DataAdapter.Update(dsModified.table). Bingo - concurrency violation because
the timestamp in the parent row has already changed.
Sample SQL:
INSERT INTO [AgencyNET].[AccessFlagLookup] ([AccessFlag], [D
escription],
[LastUpdatedBy]) VALUES (@.AccessFlag, @.Description, @.LastUpdatedBy);SELE
CT
AccessFlagLookupID, CAST(TS AS INT) AS TS FROM AgencyNET.AccessFlagLookup
WHERE (AccessFlagLookupID = SCOPE_IDENTITY())
UPDATE [AgencyNET].[AccessFlagLookup] SET [AccessFlag] = @.Access
Flag,
[Description] = @.Description, [LastUpdated] = getutcdate(), [Las
tUpdatedBy]
= @.LastUpdatedBy WHERE (([AccessFlagLookupID] =
@.Original_AccessFlagLookupID) AND (CAST(TS AS INT) = @.Original_TS));SELECT
CAST(TS AS INT) AS TS FROM AgencyNET.AccessFlagLookup WHERE
(AccessFlagLookupID = @.AccessFlagLookupID)
That "(CAST(TS AS INT) = @.Original_TS));" works with the first update with
the added rows (modified parent) but fails when it gets updated again when
the modified rows get processed.
The way I found this was through getting unexpected concurrency errors.
Stepping through the code and monitoring changes in the database timestamp
values spotted the problem.
Nasty.|||Hi,
-1- I have winform that contains some textboxes, comboboxes etc these are da
tabound to a BindingSource
-2- if the user decides to add a new record I call BindingSource.AddNew()
-2- The BindingSource is bound to my dataset.
-4- when the user clicks on the Save Record button my function looks like th
e following:
try
{
this.CustomerBindingSource.EndEdit();
this.dataSetCustomers1.Customers[CustomerBindingSource.Position].AddedBy
= "XXX";
this.dataSetCustomers1.Customers[CustomerBindingSource.Position].DateLas
tEdited = DateTime.Now;
int ncount = this.customersTableAdapter.Update(this.dataSetCustomers1.Custom
ers);
}
catch (DBConcurrencyException oEx )
{
MessageBox.Show("Concurrency Erro: " + oEx.Message);
}
catch (System.Exception ex)
{
MessageBox.Show("Other Error: " + ex.Message);
}
-5- The Dataset that is bound to the BindingSource has an identity field whi
ch is an int and is also the primary key on the table, The insert command t
hat is generated by the vs2005 designer does NOT contain the identy field bu
t does a select after the insert inorder to repopulate the dataset with the
new id as send below:
INSERT INTO [Customers] ([Date], [ContactLastName], ) VALUES (@.D
ate, @.ContactLastName);
SELECT CustomerID, Date, ContactLastName FROM Customers WHERE (CustomerID =
SCOPE_IDENTITY())
-6- I am getting some concurrency violations with updates but I am also gett
ing the odd concurrency violation with Adding new records is this possible?
also it appeard that for some reason today the update command was also not u
pdating some records down to the database, however then the app was restarte
d and for some reason it started to work..
Any help would be greatly appreciated.
Thanks,
"Jim Rand" <jimrand@.ix.netcom.com> wrote in message news:uTgwKOLKIHA.5980@.TK2MSFTNGP04.phx.g
bl...
> I'm going to make several assumptions.
>
> 1) You use identity keys in the database.
> 2) You have figured out how to get the keys back to replace negative keys
in
> your dataset that existed prior to update.
> 3) You are using timestamps for concurrency (that's a big assumption).
> 4) You process the dataset updates in chunks using the
> dataset.GetChanges(Deleted | Modified | Added)
> 5) You process the deletes first up the hierarchy. Then, you process the
> adds down the parent chain. Finally, you process the modifies.
>
> Let's say the user modified the parent row and added new child rows.
>
> Here is what I discovered. Dataset.GetChanges(DataRowState.Added) gets th
e
> added rows as you would expect. It also includes any modified parents. If
> you do a DataAdapter.Update(dsAdded.table), it will insert the new child
> rows AND will also update the parent row if it had been modified. Fine so
> far. Here is what happens next. You do the
> DataAdapter.Update(dsModified.table). Bingo - concurrency violation becaus
e
> the timestamp in the parent row has already changed.
>
> Sample SQL:
>
> INSERT INTO [AgencyNET].[AccessFlagLookup] ([AccessFlag], [
;Description],
> [LastUpdatedBy]) VALUES (@.AccessFlag, @.Description, @.LastUpdatedBy);SE
LECT
> AccessFlagLookupID, CAST(TS AS INT) AS TS FROM AgencyNET.AccessFlagLookup
> WHERE (AccessFlagLookupID = SCOPE_IDENTITY())
>
> UPDATE [AgencyNET].[AccessFlagLookup] SET [AccessFlag] = @.Acce
ssFlag,
> [Description] = @.Description, [LastUpdated] = getutcdate(), [L
astUpdatedBy]
> = @.LastUpdatedBy WHERE (([AccessFlagLookupID] =
> @.Original_AccessFlagLookupID) AND (CAST(TS AS INT) = @.Original_TS));SELECT
> CAST(TS AS INT) AS TS FROM AgencyNET.AccessFlagLookup WHERE
> (AccessFlagLookupID = @.AccessFlagLookupID)
>
> That "(CAST(TS AS INT) = @.Original_TS));" works with the first update with
> the added rows (modified parent) but fails when it gets updated again when
> the modified rows get processed.
>
> The way I found this was through getting unexpected concurrency errors.
> Stepping through the code and monitoring changes in the database timestamp
> values spotted the problem.
>
> Nasty.
>
>|||Do you have more information concerning usage patterns? I.e., is there more
than one person attempting to update/add rows simultaneously? Or is this
all happening with only a single user? Also, what is your PK on the
Customers table? What happens if you wrap the INSERT INTO...SELECT in a
BEGIN TRANSACTION...COMMIT TRANSACTION?
"Rob Dob" <robdob20012002@.yahoo.com> wrote in message
news:ubpeJ5LKIHA.484@.TK2MSFTNGP06.phx.gbl...
Hi,
-1- I have winform that contains some textboxes, comboboxes etc these are
databound to a BindingSource
-2- if the user decides to add a new record I call BindingSource.AddNew()
-2- The BindingSource is bound to my dataset.
-4- when the user clicks on the Save Record button my function looks like
the following:
try
{
this.CustomerBindingSource.EndEdit();
this.dataSetCustomers1.Customers[CustomerBindingSource.Position].AddedBy
=
"XXX";
this.dataSetCustomers1.Customers[CustomerBindingSource.Position].DateLas
tEdited
= DateTime.Now;
int ncount =
this.customersTableAdapter.Update(this.dataSetCustomers1.Customers);
}
catch (DBConcurrencyException oEx )
{
MessageBox.Show("Concurrency Erro: " + oEx.Message);
}
catch (System.Exception ex)
{
MessageBox.Show("Other Error: " + ex.Message);
}
-5- The Dataset that is bound to the BindingSource has an identity field
which is an int and is also the primary key on the table, The insert
command that is generated by the vs2005 designer does NOT contain the identy
field but does a select after the insert inorder to repopulate the dataset
with the new id as send below:
INSERT INTO [Customers] ([Date], [ContactLastName], ) VALUES (@.D
ate,
@.ContactLastName);
SELECT CustomerID, Date, ContactLastName FROM Customers WHERE (CustomerID =
SCOPE_IDENTITY())
-6- I am getting some concurrency violations with updates but I am also
getting the odd concurrency violation with Adding new records is this
possible? also it appeard that for some reason today the update command was
also not updating some records down to the database, however then the app
was restarted and for some reason it started to work..
Any help would be greatly appreciated.
Thanks,
"Jim Rand" <jimrand@.ix.netcom.com> wrote in message
news:uTgwKOLKIHA.5980@.TK2MSFTNGP04.phx.gbl...
> I'm going to make several assumptions.
> 1) You use identity keys in the database.
> 2) You have figured out how to get the keys back to replace negative keys
> in
> your dataset that existed prior to update.
> 3) You are using timestamps for concurrency (that's a big assumption).
> 4) You process the dataset updates in chunks using the
> dataset.GetChanges(Deleted | Modified | Added)
> 5) You process the deletes first up the hierarchy. Then, you process the
> adds down the parent chain. Finally, you process the modifies.
> Let's say the user modified the parent row and added new child rows.
> Here is what I discovered. Dataset.GetChanges(DataRowState.Added) gets
> the
> added rows as you would expect. It also includes any modified parents. If
> you do a DataAdapter.Update(dsAdded.table), it will insert the new child
> rows AND will also update the parent row if it had been modified. Fine so
> far. Here is what happens next. You do the
> DataAdapter.Update(dsModified.table). Bingo - concurrency violation
> because
> the timestamp in the parent row has already changed.
> Sample SQL:
> INSERT INTO [AgencyNET].[AccessFlagLookup] ([AccessFlag], [
;Description],
> [LastUpdatedBy]) VALUES (@.AccessFlag, @.Description, @.LastUpdatedBy);SE
LECT
> AccessFlagLookupID, CAST(TS AS INT) AS TS FROM AgencyNET.AccessFlagLookup
> WHERE (AccessFlagLookupID = SCOPE_IDENTITY())
> UPDATE [AgencyNET].[AccessFlagLookup] SET [AccessFlag] = @.Acce
ssFlag,
> [Description] = @.Description, [LastUpdated] = getutcdate(),
> [LastUpdatedBy]
> = @.LastUpdatedBy WHERE (([AccessFlagLookupID] =
> @.Original_AccessFlagLookupID) AND (CAST(TS AS INT) = @.Original_TS));SELECT
> CAST(TS AS INT) AS TS FROM AgencyNET.AccessFlagLookup WHERE
> (AccessFlagLookupID = @.AccessFlagLookupID)
> That "(CAST(TS AS INT) = @.Original_TS));" works with the first update with
> the added rows (modified parent) but fails when it gets updated again when
> the modified rows get processed.
> The way I found this was through getting unexpected concurrency errors.
> Stepping through the code and monitoring changes in the database timestamp
> values spotted the problem.
> Nasty.
>|||Thank you, I will try using the BeginTransaction .. Commit Transaction,
yes this is a multi-user application, about 50+ users,
Thank you, I will report back.
"Mike C#" <xyz@.xyz.com> wrote in message
news:%23lsjlpNKIHA.3400@.TK2MSFTNGP03.phx.gbl...
> Do you have more information concerning usage patterns? I.e., is there
> more than one person attempting to update/add rows simultaneously? Or is
> this all happening with only a single user? Also, what is your PK on the
> Customers table? What happens if you wrap the INSERT INTO...SELECT in a
> BEGIN TRANSACTION...COMMIT TRANSACTION?
> "Rob Dob" <robdob20012002@.yahoo.com> wrote in message
> news:ubpeJ5LKIHA.484@.TK2MSFTNGP06.phx.gbl...
> Hi,
> -1- I have winform that contains some textboxes, comboboxes etc these are
> databound to a BindingSource
> -2- if the user decides to add a new record I call BindingSource.AddNew()
> -2- The BindingSource is bound to my dataset.
> -4- when the user clicks on the Save Record button my function looks like
> the following:
> try
> {
> this.CustomerBindingSource.EndEdit();
> this.dataSetCustomers1.Customers[CustomerBindingSource.Position].Added
By =
> "XXX";
> this.dataSetCustomers1.Customers[CustomerBindingSource.Position].DateL
astEdited
> = DateTime.Now;
> int ncount =
> this.customersTableAdapter.Update(this.dataSetCustomers1.Customers);
> }
> catch (DBConcurrencyException oEx )
> {
> MessageBox.Show("Concurrency Erro: " + oEx.Message);
> }
> catch (System.Exception ex)
> {
> MessageBox.Show("Other Error: " + ex.Message);
> }
> -5- The Dataset that is bound to the BindingSource has an identity field
> which is an int and is also the primary key on the table, The insert
> command that is generated by the vs2005 designer does NOT contain the
> identy field but does a select after the insert inorder to repopulate the
> dataset with the new id as send below:
> INSERT INTO [Customers] ([Date], [ContactLastName], ) VALUES (
@.Date,
> @.ContactLastName);
> SELECT CustomerID, Date, ContactLastName FROM Customers WHERE (CustomerID
> = SCOPE_IDENTITY())
> -6- I am getting some concurrency violations with updates but I am also
> getting the odd concurrency violation with Adding new records is this
> possible? also it appeard that for some reason today the update command
> was also not updating some records down to the database, however then the
> app was restarted and for some reason it started to work..
> Any help would be greatly appreciated.
> Thanks,
>
> "Jim Rand" <jimrand@.ix.netcom.com> wrote in message
> news:uTgwKOLKIHA.5980@.TK2MSFTNGP04.phx.gbl...
>|||This problem is occurring when 50+ users are attempting to add/update rows
simultaneously then; not just one user? That's what I'm trying to discover.
And yes, please try wrapping your inserts and updates in single transactions
so we can determine if that helps alleviate the problem for you.
"Rob Dob" <robdob20012002@.yahoo.com> wrote in message
news:O0cFq5SKIHA.5328@.TK2MSFTNGP05.phx.gbl...
> Thank you, I will try using the BeginTransaction .. Commit Transaction,
> yes this is a multi-user application, about 50+ users,
> Thank you, I will report back.
> "Mike C#" <xyz@.xyz.com> wrote in message
> news:%23lsjlpNKIHA.3400@.TK2MSFTNGP03.phx.gbl...
>

Concurrency violation adding records Why?

Hi,
I'm getting periodic concurrency violations while adding new records, can
someone please tell me how to resolve this. I have an application that is
running multi-user, approx 60+ users and for some reason my application is
throwing a concurrency violation when adding a new record, I have a
bindingsource that is bound to several fields, I then issue a EndEdit()
followed by an update. 95% of the time it works and the other 5% I get a
concurrency error.. This is very frustrating. the dataset being updated
contains an identity field which is an int, I set this identity field using
the datasets autoincrement feature and autostep -1. My insert statement
does NOT contain the identity field.
Thanks,If your clustered index column is going down by 1 (increment set to negative
one) then you do realize that SQL Server has to reorganize the entire table
after every single insert? If this is the case it might be at least
contributing to/exacerbating your issue.
"Rob Dob" <robdob20012002@.yahoo.com> wrote in message
news:%23qbtuTJKIHA.3516@.TK2MSFTNGP02.phx.gbl...
> Hi,
> I'm getting periodic concurrency violations while adding new records, can
> someone please tell me how to resolve this. I have an application that
> is running multi-user, approx 60+ users and for some reason my application
> is throwing a concurrency violation when adding a new record, I have a
> bindingsource that is bound to several fields, I then issue a EndEdit()
> followed by an update. 95% of the time it works and the other 5% I get a
> concurrency error.. This is very frustrating. the dataset being updated
> contains an identity field which is an int, I set this identity field
> using the datasets autoincrement feature and autostep -1. My insert
> statement does NOT contain the identity field.
>
> Thanks,
>|||the identity column never makes it to the sql, its only their to satisfy my
datatset. when the update method of my tableadapter is called it has no
mention of the identity column.
Do you have any other ideas? thank you for your help.
"Mike C#" <xyz@.xyz.com> wrote in messa ge
news:%234qPSXKKIHA.5468@.TK2MSFTNGP05.phx.gbl...
> If your clustered index column is going down by 1 (increment set to
> negative one) then you do realize that SQL Server has to reorganize the
> entire table after every single insert? If this is the case it might be
> at least contributing to/exacerbating your issue.
> "Rob Dob" <robdob20012002@.yahoo.com> wrote in message
> news:%23qbtuTJKIHA.3516@.TK2MSFTNGP02.phx.gbl...
>> Hi,
>> I'm getting periodic concurrency violations while adding new records, can
>> someone please tell me how to resolve this. I have an application that
>> is running multi-user, approx 60+ users and for some reason my
>> application is throwing a concurrency violation when adding a new record,
>> I have a bindingsource that is bound to several fields, I then issue a
>> EndEdit() followed by an update. 95% of the time it works and the other
>> 5% I get a concurrency error.. This is very frustrating. the dataset
>> being updated contains an identity field which is an int, I set this
>> identity field using the datasets autoincrement feature and autostep -1.
>> My insert statement does NOT contain the identity field.
>>
>> Thanks,
>>
>|||I'm going to make several assumptions.
1) You use identity keys in the database.
2) You have figured out how to get the keys back to replace negative keys in
your dataset that existed prior to update.
3) You are using timestamps for concurrency (that's a big assumption).
4) You process the dataset updates in chunks using the
dataset.GetChanges(Deleted | Modified | Added)
5) You process the deletes first up the hierarchy. Then, you process the
adds down the parent chain. Finally, you process the modifies.
Let's say the user modified the parent row and added new child rows.
Here is what I discovered. Dataset.GetChanges(DataRowState.Added) gets the
added rows as you would expect. It also includes any modified parents. If
you do a DataAdapter.Update(dsAdded.table), it will insert the new child
rows AND will also update the parent row if it had been modified. Fine so
far. Here is what happens next. You do the
DataAdapter.Update(dsModified.table). Bingo - concurrency violation because
the timestamp in the parent row has already changed.
Sample SQL:
INSERT INTO [AgencyNET].[AccessFlagLookup] ([AccessFlag], [Description],
[LastUpdatedBy]) VALUES (@.AccessFlag, @.Description, @.LastUpdatedBy);SELECT
AccessFlagLookupID, CAST(TS AS INT) AS TS FROM AgencyNET.AccessFlagLookup
WHERE (AccessFlagLookupID = SCOPE_IDENTITY())
UPDATE [AgencyNET].[AccessFlagLookup] SET [AccessFlag] = @.AccessFlag,
[Description] = @.Description, [LastUpdated] = getutcdate(), [LastUpdatedBy]
= @.LastUpdatedBy WHERE (([AccessFlagLookupID] =@.Original_AccessFlagLookupID) AND (CAST(TS AS INT) = @.Original_TS));SELECT
CAST(TS AS INT) AS TS FROM AgencyNET.AccessFlagLookup WHERE
(AccessFlagLookupID = @.AccessFlagLookupID)
That "(CAST(TS AS INT) = @.Original_TS));" works with the first update with
the added rows (modified parent) but fails when it gets updated again when
the modified rows get processed.
The way I found this was through getting unexpected concurrency errors.
Stepping through the code and monitoring changes in the database timestamp
values spotted the problem.
Nasty.|||This is a multi-part message in MIME format.
--=_NextPart_000_000B_01C82894.5AB596A0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Hi,
-1- I have winform that contains some textboxes, comboboxes etc these =are databound to a BindingSource
-2- if the user decides to add a new record I call =BindingSource.AddNew()
-2- The BindingSource is bound to my dataset.
-4- when the user clicks on the Save Record button my function looks =like the following:
try
{
this.CustomerBindingSource.EndEdit();
this.dataSetCustomers1.Customers[CustomerBindingSource.Position].AddedBy ==3D "XXX";
this.dataSetCustomers1.Customers[CustomerBindingSource.Position].DateLast=Edited =3D DateTime.Now;
int ncount =3D =this.customersTableAdapter.Update(this.dataSetCustomers1.Customers);
}
catch (DBConcurrencyException oEx )
{
MessageBox.Show("Concurrency Erro: " + oEx.Message);
}
catch (System.Exception ex)
{
MessageBox.Show("Other Error: " + ex.Message);
}
-5- The Dataset that is bound to the BindingSource has an identity field =which is an int and is also the primary key on the table, The insert =command that is generated by the vs2005 designer does NOT contain the =identy field but does a select after the insert inorder to repopulate =the dataset with the new id as send below:
INSERT INTO [Customers] ([Date], [ContactLastName], ) VALUES (@.Date, =@.ContactLastName);
SELECT CustomerID, Date, ContactLastName FROM Customers WHERE =(CustomerID =3D SCOPE_IDENTITY())
-6- I am getting some concurrency violations with updates but I am also =getting the odd concurrency violation with Adding new records is this =possible? also it appeard that for some reason today the update command =was also not updating some records down to the database, however then =the app was restarted and for some reason it started to work..
Any help would be greatly appreciated.
Thanks,
"Jim Rand" <jimrand@.ix.netcom.com> wrote in message =news:uTgwKOLKIHA.5980@.TK2MSFTNGP04.phx.gbl...
> I'm going to make several assumptions.
> > 1) You use identity keys in the database.
> 2) You have figured out how to get the keys back to replace negative =keys in > your dataset that existed prior to update.
> 3) You are using timestamps for concurrency (that's a big assumption).
> 4) You process the dataset updates in chunks using the > dataset.GetChanges(Deleted | Modified | Added)
> 5) You process the deletes first up the hierarchy. Then, you process =the > adds down the parent chain. Finally, you process the modifies.
> > Let's say the user modified the parent row and added new child rows.
> > Here is what I discovered. Dataset.GetChanges(DataRowState.Added) =gets the > added rows as you would expect. It also includes any modified parents. = If > you do a DataAdapter.Update(dsAdded.table), it will insert the new =child > rows AND will also update the parent row if it had been modified. Fine =so > far. Here is what happens next. You do the > DataAdapter.Update(dsModified.table). Bingo - concurrency violation =because > the timestamp in the parent row has already changed.
> > Sample SQL:
> > INSERT INTO [AgencyNET].[AccessFlagLookup] ([AccessFlag], =[Description], > [LastUpdatedBy]) VALUES (@.AccessFlag, @.Description, =@.LastUpdatedBy);SELECT > AccessFlagLookupID, CAST(TS AS INT) AS TS FROM =AgencyNET.AccessFlagLookup > WHERE (AccessFlagLookupID =3D SCOPE_IDENTITY())
> > UPDATE [AgencyNET].[AccessFlagLookup] SET [AccessFlag] =3D =@.AccessFlag, > [Description] =3D @.Description, [LastUpdated] =3D getutcdate(), =[LastUpdatedBy] > =3D @.LastUpdatedBy WHERE (([AccessFlagLookupID] =3D > @.Original_AccessFlagLookupID) AND (CAST(TS AS INT) =3D =@.Original_TS));SELECT > CAST(TS AS INT) AS TS FROM AgencyNET.AccessFlagLookup WHERE > (AccessFlagLookupID =3D @.AccessFlagLookupID)
> > That "(CAST(TS AS INT) =3D @.Original_TS));" works with the first =update with > the added rows (modified parent) but fails when it gets updated again =when > the modified rows get processed.
> > The way I found this was through getting unexpected concurrency =errors. > Stepping through the code and monitoring changes in the database =timestamp > values spotted the problem.
> > Nasty.
> >
--=_NextPart_000_000B_01C82894.5AB596A0
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
&

Hi,-1- I have winform that =contains some textboxes, comboboxes etc these are databound to a BindingSource-2- =if the user decides to add a new record I call BindingSource.AddNew()-2- =The BindingSource is bound to my dataset.-4- when the user clicks on the =Save Record button my function looks like the following:
try{
this.CustomerBindingSource.EndEdit();this.dataSetCustomers1.Customers[CustomerBindingSource.Position]=.AddedBy =3D "XXX";this.dataSetCustomers1.Customers[CustomerBindingSource.Position=].DateLastEdited =3D DateTime.Now;int ncount =3D this.customersTableAdapter.Update(this.dataSetCustomers1.Customers);}=catch (DBConcurrencyException oEx ){MessageBox.Show("Concurrency Erro: =" + oEx.Message);}catch (System.Exception =ex){MessageBox.Show("Other Error: " + ex.Message);}-5- The Dataset that is bound to the =BindingSource has an identity field which is an int and is also the =primary key on the table, The insert command that is generated by the vs2005 =designer does NOT contain the identy field but does a select after the insert =inorder to repopulate the dataset with the new id as send below:
INSERT INTO [Customers] ([Date], =[ContactLastName], ) VALUES (@.Date, @.ContactLastName);SELECT CustomerID, Date, =ContactLastName FROM Customers WHERE (CustomerID =3D SCOPE_IDENTITY())
-6- I am getting some concurrency violations with updates but I =am also getting the odd concurrency violation with Adding new records is this =possible? also it appeard that for some reason today the update command was also =not updating some records down to the database, however then the app was =restarted and for some reason it started to work..
Any help would be greatly appreciated.
Thanks,"Jim Rand" wrote in =message news:uTgwKOLKIHA.5980@.TK2MSFTNGP04.phx.gbl...> I'm going to make =several assumptions.> > 1) You use identity keys in the =database.> 2) You have figured out how to get the keys back to replace negative =keys in > your dataset that existed prior to update.> 3) You are =using timestamps for concurrency (that's a big assumption).> 4) You =process the dataset updates in chunks using the > =dataset.GetChanges(Deleted | Modified | Added)> 5) You process the deletes first up the =hierarchy. Then, you process the > adds down the parent chain. Finally, you =process the modifies.> > Let's say the user modified the parent =row and added new child rows.> > Here is what I discovered. Dataset.GetChanges(DataRowState.Added) gets the > added rows as =you would expect. It also includes any modified parents. If > you do =a DataAdapter.Update(dsAdded.table), it will insert the new child > =rows AND will also update the parent row if it had been modified. Fine so => far. Here is what happens next. You do the > DataAdapter.Update(dsModified.table). Bingo - concurrency violation =because > the timestamp in the parent row has already changed.> => Sample SQL:> > INSERT INTO [AgencyNET].[AccessFlagLookup] ([AccessFlag], [Description], > [LastUpdatedBy]) VALUES =(@.AccessFlag, @.Description, @.LastUpdatedBy);SELECT > AccessFlagLookupID, =CAST(TS AS INT) AS TS FROM AgencyNET.AccessFlagLookup > WHERE =(AccessFlagLookupID =3D SCOPE_IDENTITY())> > UPDATE [AgencyNET].[AccessFlagLookup] =SET [AccessFlag] =3D @.AccessFlag, > [Description] =3D @.Description, =[LastUpdated] =3D getutcdate(), [LastUpdatedBy] > =3D @.LastUpdatedBy WHERE (([AccessFlagLookupID] =3D > @.Original_AccessFlagLookupID) AND =(CAST(TS AS INT) =3D @.Original_TS));SELECT > CAST(TS AS INT) AS TS FROM AgencyNET.AccessFlagLookup WHERE > (AccessFlagLookupID =3D @.AccessFlagLookupID)> > That "(CAST(TS AS INT) =3D =@.Original_TS));" works with the first update with > the added rows (modified =parent) but fails when it gets updated again when > the modified rows get processed.> > The way I found this was through getting =unexpected concurrency errors. > Stepping through the code and monitoring =changes in the database timestamp > values spotted the problem.> => Nasty.> >

--=_NextPart_000_000B_01C82894.5AB596A0--|||Do you have more information concerning usage patterns? I.e., is there more
than one person attempting to update/add rows simultaneously? Or is this
all happening with only a single user? Also, what is your PK on the
Customers table? What happens if you wrap the INSERT INTO...SELECT in a
BEGIN TRANSACTION...COMMIT TRANSACTION?
"Rob Dob" <robdob20012002@.yahoo.com> wrote in message
news:ubpeJ5LKIHA.484@.TK2MSFTNGP06.phx.gbl...
Hi,
-1- I have winform that contains some textboxes, comboboxes etc these are
databound to a BindingSource
-2- if the user decides to add a new record I call BindingSource.AddNew()
-2- The BindingSource is bound to my dataset.
-4- when the user clicks on the Save Record button my function looks like
the following:
try
{
this.CustomerBindingSource.EndEdit();
this.dataSetCustomers1.Customers[CustomerBindingSource.Position].AddedBy ="XXX";
this.dataSetCustomers1.Customers[CustomerBindingSource.Position].DateLastEdited
= DateTime.Now;
int ncount =this.customersTableAdapter.Update(this.dataSetCustomers1.Customers);
}
catch (DBConcurrencyException oEx )
{
MessageBox.Show("Concurrency Erro: " + oEx.Message);
}
catch (System.Exception ex)
{
MessageBox.Show("Other Error: " + ex.Message);
}
-5- The Dataset that is bound to the BindingSource has an identity field
which is an int and is also the primary key on the table, The insert
command that is generated by the vs2005 designer does NOT contain the identy
field but does a select after the insert inorder to repopulate the dataset
with the new id as send below:
INSERT INTO [Customers] ([Date], [ContactLastName], ) VALUES (@.Date,
@.ContactLastName);
SELECT CustomerID, Date, ContactLastName FROM Customers WHERE (CustomerID =SCOPE_IDENTITY())
-6- I am getting some concurrency violations with updates but I am also
getting the odd concurrency violation with Adding new records is this
possible? also it appeard that for some reason today the update command was
also not updating some records down to the database, however then the app
was restarted and for some reason it started to work..
Any help would be greatly appreciated.
Thanks,
"Jim Rand" <jimrand@.ix.netcom.com> wrote in message
news:uTgwKOLKIHA.5980@.TK2MSFTNGP04.phx.gbl...
> I'm going to make several assumptions.
> 1) You use identity keys in the database.
> 2) You have figured out how to get the keys back to replace negative keys
> in
> your dataset that existed prior to update.
> 3) You are using timestamps for concurrency (that's a big assumption).
> 4) You process the dataset updates in chunks using the
> dataset.GetChanges(Deleted | Modified | Added)
> 5) You process the deletes first up the hierarchy. Then, you process the
> adds down the parent chain. Finally, you process the modifies.
> Let's say the user modified the parent row and added new child rows.
> Here is what I discovered. Dataset.GetChanges(DataRowState.Added) gets
> the
> added rows as you would expect. It also includes any modified parents. If
> you do a DataAdapter.Update(dsAdded.table), it will insert the new child
> rows AND will also update the parent row if it had been modified. Fine so
> far. Here is what happens next. You do the
> DataAdapter.Update(dsModified.table). Bingo - concurrency violation
> because
> the timestamp in the parent row has already changed.
> Sample SQL:
> INSERT INTO [AgencyNET].[AccessFlagLookup] ([AccessFlag], [Description],
> [LastUpdatedBy]) VALUES (@.AccessFlag, @.Description, @.LastUpdatedBy);SELECT
> AccessFlagLookupID, CAST(TS AS INT) AS TS FROM AgencyNET.AccessFlagLookup
> WHERE (AccessFlagLookupID = SCOPE_IDENTITY())
> UPDATE [AgencyNET].[AccessFlagLookup] SET [AccessFlag] = @.AccessFlag,
> [Description] = @.Description, [LastUpdated] = getutcdate(),
> [LastUpdatedBy]
> = @.LastUpdatedBy WHERE (([AccessFlagLookupID] => @.Original_AccessFlagLookupID) AND (CAST(TS AS INT) = @.Original_TS));SELECT
> CAST(TS AS INT) AS TS FROM AgencyNET.AccessFlagLookup WHERE
> (AccessFlagLookupID = @.AccessFlagLookupID)
> That "(CAST(TS AS INT) = @.Original_TS));" works with the first update with
> the added rows (modified parent) but fails when it gets updated again when
> the modified rows get processed.
> The way I found this was through getting unexpected concurrency errors.
> Stepping through the code and monitoring changes in the database timestamp
> values spotted the problem.
> Nasty.
>|||Thank you, I will try using the BeginTransaction .. Commit Transaction,
yes this is a multi-user application, about 50+ users,
Thank you, I will report back.
"Mike C#" <xyz@.xyz.com> wrote in message
news:%23lsjlpNKIHA.3400@.TK2MSFTNGP03.phx.gbl...
> Do you have more information concerning usage patterns? I.e., is there
> more than one person attempting to update/add rows simultaneously? Or is
> this all happening with only a single user? Also, what is your PK on the
> Customers table? What happens if you wrap the INSERT INTO...SELECT in a
> BEGIN TRANSACTION...COMMIT TRANSACTION?
> "Rob Dob" <robdob20012002@.yahoo.com> wrote in message
> news:ubpeJ5LKIHA.484@.TK2MSFTNGP06.phx.gbl...
> Hi,
> -1- I have winform that contains some textboxes, comboboxes etc these are
> databound to a BindingSource
> -2- if the user decides to add a new record I call BindingSource.AddNew()
> -2- The BindingSource is bound to my dataset.
> -4- when the user clicks on the Save Record button my function looks like
> the following:
> try
> {
> this.CustomerBindingSource.EndEdit();
> this.dataSetCustomers1.Customers[CustomerBindingSource.Position].AddedBy => "XXX";
> this.dataSetCustomers1.Customers[CustomerBindingSource.Position].DateLastEdited
> = DateTime.Now;
> int ncount => this.customersTableAdapter.Update(this.dataSetCustomers1.Customers);
> }
> catch (DBConcurrencyException oEx )
> {
> MessageBox.Show("Concurrency Erro: " + oEx.Message);
> }
> catch (System.Exception ex)
> {
> MessageBox.Show("Other Error: " + ex.Message);
> }
> -5- The Dataset that is bound to the BindingSource has an identity field
> which is an int and is also the primary key on the table, The insert
> command that is generated by the vs2005 designer does NOT contain the
> identy field but does a select after the insert inorder to repopulate the
> dataset with the new id as send below:
> INSERT INTO [Customers] ([Date], [ContactLastName], ) VALUES (@.Date,
> @.ContactLastName);
> SELECT CustomerID, Date, ContactLastName FROM Customers WHERE (CustomerID
> = SCOPE_IDENTITY())
> -6- I am getting some concurrency violations with updates but I am also
> getting the odd concurrency violation with Adding new records is this
> possible? also it appeard that for some reason today the update command
> was also not updating some records down to the database, however then the
> app was restarted and for some reason it started to work..
> Any help would be greatly appreciated.
> Thanks,
>
> "Jim Rand" <jimrand@.ix.netcom.com> wrote in message
> news:uTgwKOLKIHA.5980@.TK2MSFTNGP04.phx.gbl...
>> I'm going to make several assumptions.
>> 1) You use identity keys in the database.
>> 2) You have figured out how to get the keys back to replace negative keys
>> in
>> your dataset that existed prior to update.
>> 3) You are using timestamps for concurrency (that's a big assumption).
>> 4) You process the dataset updates in chunks using the
>> dataset.GetChanges(Deleted | Modified | Added)
>> 5) You process the deletes first up the hierarchy. Then, you process the
>> adds down the parent chain. Finally, you process the modifies.
>> Let's say the user modified the parent row and added new child rows.
>> Here is what I discovered. Dataset.GetChanges(DataRowState.Added) gets
>> the
>> added rows as you would expect. It also includes any modified parents.
>> If
>> you do a DataAdapter.Update(dsAdded.table), it will insert the new child
>> rows AND will also update the parent row if it had been modified. Fine so
>> far. Here is what happens next. You do the
>> DataAdapter.Update(dsModified.table). Bingo - concurrency violation
>> because
>> the timestamp in the parent row has already changed.
>> Sample SQL:
>> INSERT INTO [AgencyNET].[AccessFlagLookup] ([AccessFlag], [Description],
>> [LastUpdatedBy]) VALUES (@.AccessFlag, @.Description,
>> @.LastUpdatedBy);SELECT
>> AccessFlagLookupID, CAST(TS AS INT) AS TS FROM AgencyNET.AccessFlagLookup
>> WHERE (AccessFlagLookupID = SCOPE_IDENTITY())
>> UPDATE [AgencyNET].[AccessFlagLookup] SET [AccessFlag] = @.AccessFlag,
>> [Description] = @.Description, [LastUpdated] = getutcdate(),
>> [LastUpdatedBy]
>> = @.LastUpdatedBy WHERE (([AccessFlagLookupID] =>> @.Original_AccessFlagLookupID) AND (CAST(TS AS INT) =>> @.Original_TS));SELECT
>> CAST(TS AS INT) AS TS FROM AgencyNET.AccessFlagLookup WHERE
>> (AccessFlagLookupID = @.AccessFlagLookupID)
>> That "(CAST(TS AS INT) = @.Original_TS));" works with the first update
>> with
>> the added rows (modified parent) but fails when it gets updated again
>> when
>> the modified rows get processed.
>> The way I found this was through getting unexpected concurrency errors.
>> Stepping through the code and monitoring changes in the database
>> timestamp
>> values spotted the problem.
>> Nasty.
>>
>|||This problem is occurring when 50+ users are attempting to add/update rows
simultaneously then; not just one user? That's what I'm trying to discover.
And yes, please try wrapping your inserts and updates in single transactions
so we can determine if that helps alleviate the problem for you.
"Rob Dob" <robdob20012002@.yahoo.com> wrote in message
news:O0cFq5SKIHA.5328@.TK2MSFTNGP05.phx.gbl...
> Thank you, I will try using the BeginTransaction .. Commit Transaction,
> yes this is a multi-user application, about 50+ users,
> Thank you, I will report back.
> "Mike C#" <xyz@.xyz.com> wrote in message
> news:%23lsjlpNKIHA.3400@.TK2MSFTNGP03.phx.gbl...
>> Do you have more information concerning usage patterns? I.e., is there
>> more than one person attempting to update/add rows simultaneously? Or is
>> this all happening with only a single user? Also, what is your PK on the
>> Customers table? What happens if you wrap the INSERT INTO...SELECT in a
>> BEGIN TRANSACTION...COMMIT TRANSACTION?
>> "Rob Dob" <robdob20012002@.yahoo.com> wrote in message
>> news:ubpeJ5LKIHA.484@.TK2MSFTNGP06.phx.gbl...
>> Hi,
>> -1- I have winform that contains some textboxes, comboboxes etc these are
>> databound to a BindingSource
>> -2- if the user decides to add a new record I call BindingSource.AddNew()
>> -2- The BindingSource is bound to my dataset.
>> -4- when the user clicks on the Save Record button my function looks like
>> the following:
>> try
>> {
>> this.CustomerBindingSource.EndEdit();
>> this.dataSetCustomers1.Customers[CustomerBindingSource.Position].AddedBy
>> = "XXX";
>> this.dataSetCustomers1.Customers[CustomerBindingSource.Position].DateLastEdited
>> = DateTime.Now;
>> int ncount =>> this.customersTableAdapter.Update(this.dataSetCustomers1.Customers);
>> }
>> catch (DBConcurrencyException oEx )
>> {
>> MessageBox.Show("Concurrency Erro: " + oEx.Message);
>> }
>> catch (System.Exception ex)
>> {
>> MessageBox.Show("Other Error: " + ex.Message);
>> }
>> -5- The Dataset that is bound to the BindingSource has an identity field
>> which is an int and is also the primary key on the table, The insert
>> command that is generated by the vs2005 designer does NOT contain the
>> identy field but does a select after the insert inorder to repopulate the
>> dataset with the new id as send below:
>> INSERT INTO [Customers] ([Date], [ContactLastName], ) VALUES (@.Date,
>> @.ContactLastName);
>> SELECT CustomerID, Date, ContactLastName FROM Customers WHERE (CustomerID
>> = SCOPE_IDENTITY())
>> -6- I am getting some concurrency violations with updates but I am also
>> getting the odd concurrency violation with Adding new records is this
>> possible? also it appeard that for some reason today the update command
>> was also not updating some records down to the database, however then the
>> app was restarted and for some reason it started to work..
>> Any help would be greatly appreciated.
>> Thanks,
>>
>> "Jim Rand" <jimrand@.ix.netcom.com> wrote in message
>> news:uTgwKOLKIHA.5980@.TK2MSFTNGP04.phx.gbl...
>> I'm going to make several assumptions.
>> 1) You use identity keys in the database.
>> 2) You have figured out how to get the keys back to replace negative
>> keys in
>> your dataset that existed prior to update.
>> 3) You are using timestamps for concurrency (that's a big assumption).
>> 4) You process the dataset updates in chunks using the
>> dataset.GetChanges(Deleted | Modified | Added)
>> 5) You process the deletes first up the hierarchy. Then, you process the
>> adds down the parent chain. Finally, you process the modifies.
>> Let's say the user modified the parent row and added new child rows.
>> Here is what I discovered. Dataset.GetChanges(DataRowState.Added) gets
>> the
>> added rows as you would expect. It also includes any modified parents.
>> If
>> you do a DataAdapter.Update(dsAdded.table), it will insert the new child
>> rows AND will also update the parent row if it had been modified. Fine
>> so
>> far. Here is what happens next. You do the
>> DataAdapter.Update(dsModified.table). Bingo - concurrency violation
>> because
>> the timestamp in the parent row has already changed.
>> Sample SQL:
>> INSERT INTO [AgencyNET].[AccessFlagLookup] ([AccessFlag], [Description],
>> [LastUpdatedBy]) VALUES (@.AccessFlag, @.Description,
>> @.LastUpdatedBy);SELECT
>> AccessFlagLookupID, CAST(TS AS INT) AS TS FROM
>> AgencyNET.AccessFlagLookup
>> WHERE (AccessFlagLookupID = SCOPE_IDENTITY())
>> UPDATE [AgencyNET].[AccessFlagLookup] SET [AccessFlag] = @.AccessFlag,
>> [Description] = @.Description, [LastUpdated] = getutcdate(),
>> [LastUpdatedBy]
>> = @.LastUpdatedBy WHERE (([AccessFlagLookupID] =>> @.Original_AccessFlagLookupID) AND (CAST(TS AS INT) =>> @.Original_TS));SELECT
>> CAST(TS AS INT) AS TS FROM AgencyNET.AccessFlagLookup WHERE
>> (AccessFlagLookupID = @.AccessFlagLookupID)
>> That "(CAST(TS AS INT) = @.Original_TS));" works with the first update
>> with
>> the added rows (modified parent) but fails when it gets updated again
>> when
>> the modified rows get processed.
>> The way I found this was through getting unexpected concurrency errors.
>> Stepping through the code and monitoring changes in the database
>> timestamp
>> values spotted the problem.
>> Nasty.
>>
>>
>

Concurrency violation adding records Why?

Hi,
I'm getting periodic concurrency violations while adding new records, can
someone please tell me how to resolve this. I have an application that is
running multi-user, approx 60+ users and for some reason my application is
throwing a concurrency violation when adding a new record, I have a
bindingsource that is bound to several fields, I then issue a EndEdit()
followed by an update. 95% of the time it works and the other 5% I get a
concurrency error.. This is very frustrating. the dataset being updated
contains an identity field which is an int, I set this identity field using
the datasets autoincrement feature and autostep -1. My insert statement
does NOT contain the identity field.
Thanks,
If your clustered index column is going down by 1 (increment set to negative
one) then you do realize that SQL Server has to reorganize the entire table
after every single insert? If this is the case it might be at least
contributing to/exacerbating your issue.
"Rob Dob" <robdob20012002@.yahoo.com> wrote in message
news:%23qbtuTJKIHA.3516@.TK2MSFTNGP02.phx.gbl...
> Hi,
> I'm getting periodic concurrency violations while adding new records, can
> someone please tell me how to resolve this. I have an application that
> is running multi-user, approx 60+ users and for some reason my application
> is throwing a concurrency violation when adding a new record, I have a
> bindingsource that is bound to several fields, I then issue a EndEdit()
> followed by an update. 95% of the time it works and the other 5% I get a
> concurrency error.. This is very frustrating. the dataset being updated
> contains an identity field which is an int, I set this identity field
> using the datasets autoincrement feature and autostep -1. My insert
> statement does NOT contain the identity field.
>
> Thanks,
>
|||the identity column never makes it to the sql, its only their to satisfy my
datatset. when the update method of my tableadapter is called it has no
mention of the identity column.
Do you have any other ideas? thank you for your help.
"Mike C#" <xyz@.xyz.com> wrote in messa ge
news:%234qPSXKKIHA.5468@.TK2MSFTNGP05.phx.gbl...
> If your clustered index column is going down by 1 (increment set to
> negative one) then you do realize that SQL Server has to reorganize the
> entire table after every single insert? If this is the case it might be
> at least contributing to/exacerbating your issue.
> "Rob Dob" <robdob20012002@.yahoo.com> wrote in message
> news:%23qbtuTJKIHA.3516@.TK2MSFTNGP02.phx.gbl...
>
|||I'm going to make several assumptions.
1) You use identity keys in the database.
2) You have figured out how to get the keys back to replace negative keys in
your dataset that existed prior to update.
3) You are using timestamps for concurrency (that's a big assumption).
4) You process the dataset updates in chunks using the
dataset.GetChanges(Deleted | Modified | Added)
5) You process the deletes first up the hierarchy. Then, you process the
adds down the parent chain. Finally, you process the modifies.
Let's say the user modified the parent row and added new child rows.
Here is what I discovered. Dataset.GetChanges(DataRowState.Added) gets the
added rows as you would expect. It also includes any modified parents. If
you do a DataAdapter.Update(dsAdded.table), it will insert the new child
rows AND will also update the parent row if it had been modified. Fine so
far. Here is what happens next. You do the
DataAdapter.Update(dsModified.table). Bingo - concurrency violation because
the timestamp in the parent row has already changed.
Sample SQL:
INSERT INTO [AgencyNET].[AccessFlagLookup] ([AccessFlag], [Description],
[LastUpdatedBy]) VALUES (@.AccessFlag, @.Description, @.LastUpdatedBy);SELECT
AccessFlagLookupID, CAST(TS AS INT) AS TS FROM AgencyNET.AccessFlagLookup
WHERE (AccessFlagLookupID = SCOPE_IDENTITY())
UPDATE [AgencyNET].[AccessFlagLookup] SET [AccessFlag] = @.AccessFlag,
[Description] = @.Description, [LastUpdated] = getutcdate(), [LastUpdatedBy]
= @.LastUpdatedBy WHERE (([AccessFlagLookupID] =
@.Original_AccessFlagLookupID) AND (CAST(TS AS INT) = @.Original_TS));SELECT
CAST(TS AS INT) AS TS FROM AgencyNET.AccessFlagLookup WHERE
(AccessFlagLookupID = @.AccessFlagLookupID)
That "(CAST(TS AS INT) = @.Original_TS));" works with the first update with
the added rows (modified parent) but fails when it gets updated again when
the modified rows get processed.
The way I found this was through getting unexpected concurrency errors.
Stepping through the code and monitoring changes in the database timestamp
values spotted the problem.
Nasty.
|||Hi,
-1- I have winform that contains some textboxes, comboboxes etc these are databound to a BindingSource
-2- if the user decides to add a new record I call BindingSource.AddNew()
-2- The BindingSource is bound to my dataset.
-4- when the user clicks on the Save Record button my function looks like the following:
try
{
this.CustomerBindingSource.EndEdit();
this.dataSetCustomers1.Customers[CustomerBindingSo urce.Position].AddedBy = "XXX";
this.dataSetCustomers1.Customers[CustomerBindingSo urce.Position].DateLastEdited = DateTime.Now;
int ncount = this.customersTableAdapter.Update(this.dataSetCust omers1.Customers);
}
catch (DBConcurrencyException oEx )
{
MessageBox.Show("Concurrency Erro: " + oEx.Message);
}
catch (System.Exception ex)
{
MessageBox.Show("Other Error: " + ex.Message);
}
-5- The Dataset that is bound to the BindingSource has an identity field which is an int and is also the primary key on the table, The insert command that is generated by the vs2005 designer does NOT contain the identy field but does a select after the insert inorder to repopulate the dataset with the new id as send below:
INSERT INTO [Customers] ([Date], [ContactLastName], ) VALUES (@.Date, @.ContactLastName);
SELECT CustomerID, Date, ContactLastName FROM Customers WHERE (CustomerID = SCOPE_IDENTITY())
-6- I am getting some concurrency violations with updates but I am also getting the odd concurrency violation with Adding new records is this possible? also it appeard that for some reason today the update command was also not updating some records down to the database, however then the app was restarted and for some reason it started to work..
Any help would be greatly appreciated.
Thanks,
"Jim Rand" <jimrand@.ix.netcom.com> wrote in message news:uTgwKOLKIHA.5980@.TK2MSFTNGP04.phx.gbl...
> I'm going to make several assumptions.
> 1) You use identity keys in the database.
> 2) You have figured out how to get the keys back to replace negative keys in
> your dataset that existed prior to update.
> 3) You are using timestamps for concurrency (that's a big assumption).
> 4) You process the dataset updates in chunks using the
> dataset.GetChanges(Deleted | Modified | Added)
> 5) You process the deletes first up the hierarchy. Then, you process the
> adds down the parent chain. Finally, you process the modifies.
> Let's say the user modified the parent row and added new child rows.
> Here is what I discovered. Dataset.GetChanges(DataRowState.Added) gets the
> added rows as you would expect. It also includes any modified parents. If
> you do a DataAdapter.Update(dsAdded.table), it will insert the new child
> rows AND will also update the parent row if it had been modified. Fine so
> far. Here is what happens next. You do the
> DataAdapter.Update(dsModified.table). Bingo - concurrency violation because
> the timestamp in the parent row has already changed.
> Sample SQL:
> INSERT INTO [AgencyNET].[AccessFlagLookup] ([AccessFlag], [Description],
> [LastUpdatedBy]) VALUES (@.AccessFlag, @.Description, @.LastUpdatedBy);SELECT
> AccessFlagLookupID, CAST(TS AS INT) AS TS FROM AgencyNET.AccessFlagLookup
> WHERE (AccessFlagLookupID = SCOPE_IDENTITY())
> UPDATE [AgencyNET].[AccessFlagLookup] SET [AccessFlag] = @.AccessFlag,
> [Description] = @.Description, [LastUpdated] = getutcdate(), [LastUpdatedBy]
> = @.LastUpdatedBy WHERE (([AccessFlagLookupID] =
> @.Original_AccessFlagLookupID) AND (CAST(TS AS INT) = @.Original_TS));SELECT
> CAST(TS AS INT) AS TS FROM AgencyNET.AccessFlagLookup WHERE
> (AccessFlagLookupID = @.AccessFlagLookupID)
> That "(CAST(TS AS INT) = @.Original_TS));" works with the first update with
> the added rows (modified parent) but fails when it gets updated again when
> the modified rows get processed.
> The way I found this was through getting unexpected concurrency errors.
> Stepping through the code and monitoring changes in the database timestamp
> values spotted the problem.
> Nasty.
>
|||Do you have more information concerning usage patterns? I.e., is there more
than one person attempting to update/add rows simultaneously? Or is this
all happening with only a single user? Also, what is your PK on the
Customers table? What happens if you wrap the INSERT INTO...SELECT in a
BEGIN TRANSACTION...COMMIT TRANSACTION?
"Rob Dob" <robdob20012002@.yahoo.com> wrote in message
news:ubpeJ5LKIHA.484@.TK2MSFTNGP06.phx.gbl...
Hi,
-1- I have winform that contains some textboxes, comboboxes etc these are
databound to a BindingSource
-2- if the user decides to add a new record I call BindingSource.AddNew()
-2- The BindingSource is bound to my dataset.
-4- when the user clicks on the Save Record button my function looks like
the following:
try
{
this.CustomerBindingSource.EndEdit();
this.dataSetCustomers1.Customers[CustomerBindingSo urce.Position].AddedBy =
"XXX";
this.dataSetCustomers1.Customers[CustomerBindingSo urce.Position].DateLastEdited
= DateTime.Now;
int ncount =
this.customersTableAdapter.Update(this.dataSetCust omers1.Customers);
}
catch (DBConcurrencyException oEx )
{
MessageBox.Show("Concurrency Erro: " + oEx.Message);
}
catch (System.Exception ex)
{
MessageBox.Show("Other Error: " + ex.Message);
}
-5- The Dataset that is bound to the BindingSource has an identity field
which is an int and is also the primary key on the table, The insert
command that is generated by the vs2005 designer does NOT contain the identy
field but does a select after the insert inorder to repopulate the dataset
with the new id as send below:
INSERT INTO [Customers] ([Date], [ContactLastName], ) VALUES (@.Date,
@.ContactLastName);
SELECT CustomerID, Date, ContactLastName FROM Customers WHERE (CustomerID =
SCOPE_IDENTITY())
-6- I am getting some concurrency violations with updates but I am also
getting the odd concurrency violation with Adding new records is this
possible? also it appeard that for some reason today the update command was
also not updating some records down to the database, however then the app
was restarted and for some reason it started to work..
Any help would be greatly appreciated.
Thanks,
"Jim Rand" <jimrand@.ix.netcom.com> wrote in message
news:uTgwKOLKIHA.5980@.TK2MSFTNGP04.phx.gbl...
> I'm going to make several assumptions.
> 1) You use identity keys in the database.
> 2) You have figured out how to get the keys back to replace negative keys
> in
> your dataset that existed prior to update.
> 3) You are using timestamps for concurrency (that's a big assumption).
> 4) You process the dataset updates in chunks using the
> dataset.GetChanges(Deleted | Modified | Added)
> 5) You process the deletes first up the hierarchy. Then, you process the
> adds down the parent chain. Finally, you process the modifies.
> Let's say the user modified the parent row and added new child rows.
> Here is what I discovered. Dataset.GetChanges(DataRowState.Added) gets
> the
> added rows as you would expect. It also includes any modified parents. If
> you do a DataAdapter.Update(dsAdded.table), it will insert the new child
> rows AND will also update the parent row if it had been modified. Fine so
> far. Here is what happens next. You do the
> DataAdapter.Update(dsModified.table). Bingo - concurrency violation
> because
> the timestamp in the parent row has already changed.
> Sample SQL:
> INSERT INTO [AgencyNET].[AccessFlagLookup] ([AccessFlag], [Description],
> [LastUpdatedBy]) VALUES (@.AccessFlag, @.Description, @.LastUpdatedBy);SELECT
> AccessFlagLookupID, CAST(TS AS INT) AS TS FROM AgencyNET.AccessFlagLookup
> WHERE (AccessFlagLookupID = SCOPE_IDENTITY())
> UPDATE [AgencyNET].[AccessFlagLookup] SET [AccessFlag] = @.AccessFlag,
> [Description] = @.Description, [LastUpdated] = getutcdate(),
> [LastUpdatedBy]
> = @.LastUpdatedBy WHERE (([AccessFlagLookupID] =
> @.Original_AccessFlagLookupID) AND (CAST(TS AS INT) = @.Original_TS));SELECT
> CAST(TS AS INT) AS TS FROM AgencyNET.AccessFlagLookup WHERE
> (AccessFlagLookupID = @.AccessFlagLookupID)
> That "(CAST(TS AS INT) = @.Original_TS));" works with the first update with
> the added rows (modified parent) but fails when it gets updated again when
> the modified rows get processed.
> The way I found this was through getting unexpected concurrency errors.
> Stepping through the code and monitoring changes in the database timestamp
> values spotted the problem.
> Nasty.
>
|||Thank you, I will try using the BeginTransaction .. Commit Transaction,
yes this is a multi-user application, about 50+ users,
Thank you, I will report back.
"Mike C#" <xyz@.xyz.com> wrote in message
news:%23lsjlpNKIHA.3400@.TK2MSFTNGP03.phx.gbl...
> Do you have more information concerning usage patterns? I.e., is there
> more than one person attempting to update/add rows simultaneously? Or is
> this all happening with only a single user? Also, what is your PK on the
> Customers table? What happens if you wrap the INSERT INTO...SELECT in a
> BEGIN TRANSACTION...COMMIT TRANSACTION?
> "Rob Dob" <robdob20012002@.yahoo.com> wrote in message
> news:ubpeJ5LKIHA.484@.TK2MSFTNGP06.phx.gbl...
> Hi,
> -1- I have winform that contains some textboxes, comboboxes etc these are
> databound to a BindingSource
> -2- if the user decides to add a new record I call BindingSource.AddNew()
> -2- The BindingSource is bound to my dataset.
> -4- when the user clicks on the Save Record button my function looks like
> the following:
> try
> {
> this.CustomerBindingSource.EndEdit();
> this.dataSetCustomers1.Customers[CustomerBindingSo urce.Position].AddedBy =
> "XXX";
> this.dataSetCustomers1.Customers[CustomerBindingSo urce.Position].DateLastEdited
> = DateTime.Now;
> int ncount =
> this.customersTableAdapter.Update(this.dataSetCust omers1.Customers);
> }
> catch (DBConcurrencyException oEx )
> {
> MessageBox.Show("Concurrency Erro: " + oEx.Message);
> }
> catch (System.Exception ex)
> {
> MessageBox.Show("Other Error: " + ex.Message);
> }
> -5- The Dataset that is bound to the BindingSource has an identity field
> which is an int and is also the primary key on the table, The insert
> command that is generated by the vs2005 designer does NOT contain the
> identy field but does a select after the insert inorder to repopulate the
> dataset with the new id as send below:
> INSERT INTO [Customers] ([Date], [ContactLastName], ) VALUES (@.Date,
> @.ContactLastName);
> SELECT CustomerID, Date, ContactLastName FROM Customers WHERE (CustomerID
> = SCOPE_IDENTITY())
> -6- I am getting some concurrency violations with updates but I am also
> getting the odd concurrency violation with Adding new records is this
> possible? also it appeard that for some reason today the update command
> was also not updating some records down to the database, however then the
> app was restarted and for some reason it started to work..
> Any help would be greatly appreciated.
> Thanks,
>
> "Jim Rand" <jimrand@.ix.netcom.com> wrote in message
> news:uTgwKOLKIHA.5980@.TK2MSFTNGP04.phx.gbl...
>
|||This problem is occurring when 50+ users are attempting to add/update rows
simultaneously then; not just one user? That's what I'm trying to discover.
And yes, please try wrapping your inserts and updates in single transactions
so we can determine if that helps alleviate the problem for you.
"Rob Dob" <robdob20012002@.yahoo.com> wrote in message
news:O0cFq5SKIHA.5328@.TK2MSFTNGP05.phx.gbl...
> Thank you, I will try using the BeginTransaction .. Commit Transaction,
> yes this is a multi-user application, about 50+ users,
> Thank you, I will report back.
> "Mike C#" <xyz@.xyz.com> wrote in message
> news:%23lsjlpNKIHA.3400@.TK2MSFTNGP03.phx.gbl...
>

Concurrency question

Suppose process A is updating record #1 in table T.
By default, can other processes read record #1 while the updating is in progress ??
If the answer is Yes, then which value can they see - the old one or the new one ?
Thank you in advance.Check this...

http://www.sql-server-performance.com/at_sql_locking.asp

Concurrency puzzle (ODBC API related)

I hope this is not outside the scope of this newsgroup.

have been useing BulkAdd with ms-access with good success.
Until now that I;m switching to MSDE which is on a shared server.

The problem is that MSDE gives an error:
Invalid attribute/option identifier, sql state=HY092
which corresponds to:
SQL_ATTR_CONCURRENCY statement attribute was set to SQL_CONCUR_READ_ONLY.

but my BulkAdd routine explicitly has a call to:
SQLSetStmtAttr(stHndl, SQL_ATTR_CONCURRENCY, SQL_CONCUR_LOCK , iRet)

I cannot imagine how the concurrency is readonly.
Could it be that I'm looking at the wrong place or the wrong attribute?

Thanks in adv.Ernesto (tsh@.mathematicuslabs.com) writes:
> have been useing BulkAdd with ms-access with good success.
> Until now that I;m switching to MSDE which is on a shared server.
> The problem is that MSDE gives an error:
> Invalid attribute/option identifier, sql state=HY092
> which corresponds to:
> SQL_ATTR_CONCURRENCY statement attribute was set to SQL_CONCUR_READ_ONLY.
> but my BulkAdd routine explicitly has a call to:
> SQLSetStmtAttr(stHndl, SQL_ATTR_CONCURRENCY, SQL_CONCUR_LOCK , iRet)
> I cannot imagine how the concurrency is readonly.
> Could it be that I'm looking at the wrong place or the wrong attribute?

Without seeing your code, it is not possible to give a definitive answer.
(And it doesn't help that I have little experience of ODBC API programming.)

But checking the docs, my conclusion is that the SELECT statement for your
cursor is such that the cursor is not updatable. This could be due to
several causes: lack of primary key, use of expressions etc. Would need to
see the SQL code together with some information on the table to say more.
--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp|||Erland ,
You are good!
I changed the query which created the table to create a primary key and it
SEEMS to solve the problem.
(It's a good thing having a primary key is ok in this case, else I would not
know how to "solve" this.)

I'm not completely out of the woods yet, but I think now there is another
unrelated problem.
Hopefully you'll keep reading if I am fooled and the problem is still there.

Now if you can only tell me how or where in the world can I learn these
things about the odbc api.

Not having found any good resource which explains these things, the way I
operate is by prayer only and geenrous people like yourself.

E|||Ernesto (tsh@.mathematicuslabs.com) writes:
> Now if you can only tell me how or where in the world can I learn these
> things about the odbc api.

The place to read about the ODBC API in general is the MDAC Books Online,
which comes with the MDAC SDK. Then there is a section in the SQL Server
Books Online which covers specifics for the SQL Server ODBC Driver.

For this particular issue, though, it's more of a general understanding
of databases in general, and in this particular case about cursors. I
know that Kalen Deleany has a chapter on cursors in her "Inside SQL
Server 2000". I doubt that she says much about ODBC, but the same issues
apply when you use cursors in T-SQL.

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp|||Thank you for the sources. I will look them up.
One more dumb question in case you can respond:

How would I do this if I did not want to add a primary key to the table?|||On Wed, 7 Jul 2004 14:20:02 -0400, Ernesto wrote:

> Thank you for the sources. I will look them up.
> One more dumb question in case you can respond:
> How would I do this if I did not want to add a primary key to the table?

You could add it to a temporary table that did have a primary key, then
execute an INSERT INTO command to transfer it to the permanent table.

However, a primary key is almost always a good idea. Some will argue that
without a primary key it isn't a table at all.|||>> How would I do this if I did not want to add a primary key to the
table? <<

Without a key, this is not a table; it is a punch card file with a
little class. You would return to what we used to call "EDP"
(Electronic Data Processing) in the late 1950's and throw away all 30
years of progress.

Well, you asked and that is the answer.

--CELKO--
===========================
Please post DDL, so that people do not have to guess what the keys,
constraints, Declarative Referential Integrity, datatypes, etc. in your
schema are.

*** Sent via Devdex http://www.devdex.com ***
Don't just participate in USENET...get rewarded for it!

Concurrency problems

Hi all,
Suppose that client A and client B read a record and B begins editing that.
Meanwhile A attempts to delete the record. Our project's rules says that the
record must not be deleted while it is being edited by other user. Whereas
our clients are disconnected, client B cannot lock the record. How can I
solve this problem?
Any help would be greatly appreciated.
Leila
I'm not sure what you mean by 'our clients are disconnected' but you
could throw the Primary Key value of the row being edited into a table.
A "this row is locked" table of sorts. Then any other user reading
that row you require your application to check your Lock table for the
Primary key value, if it is found then you return a message saying "you
can't delete this record, it's being edited by another user." Or
something like that, we've done that for our OLTP system in the past.
|||One way to solve this is to never delete a row. Add a column called
'Visible' that will act as a boolean for the UI to display or not display
the row. When a user 'deletes' a row, the row should really just be marked
as not visible. Then you can implement some logic (via a trigger) such that
if a row is updated when it's marked 'not visible', it will be marked
'visible' again.
Adam Machanic
SQL Server MVP
http://www.sqljunkies.com/weblog/amachanic
"Leila" <Leilas@.hotpop.com> wrote in message
news:eU2lWsE5EHA.1596@.tk2msftngp13.phx.gbl...
> Hi all,
> Suppose that client A and client B read a record and B begins editing
that.
> Meanwhile A attempts to delete the record. Our project's rules says that
the
> record must not be deleted while it is being edited by other user. Whereas
> our clients are disconnected, client B cannot lock the record. How can I
> solve this problem?
> Any help would be greatly appreciated.
> Leila
>
|||Adam Machanic wrote:
> One way to solve this is to never delete a row. Add a column called
> 'Visible' that will act as a boolean for the UI to display or not
display
> the row. When a user 'deletes' a row, the row should really just be
marked
> as not visible. Then you can implement some logic (via a trigger)
such that[vbcol=seagreen]
> if a row is updated when it's marked 'not visible', it will be marked
> 'visible' again.
> --
> Adam Machanic
> SQL Server MVP
> http://www.sqljunkies.com/weblog/amachanic
> --
>
> "Leila" <Leilas@.hotpop.com> wrote in message
> news:eU2lWsE5EHA.1596@.tk2msftngp13.phx.gbl...
editing[vbcol=seagreen]
> that.
that[vbcol=seagreen]
> the
Whereas[vbcol=seagreen]
can I[vbcol=seagreen]
Adam,
I have one question about this method, and I'm not questioning the
validity of this solution so please don't take my question the wrong
way. My question is about spliting the table by using the Visible bit
and querying on the table later. Wouldn't you have to always use that
bit on your Selects and therefore not having the most effecient "index"
of sorts to use when you are retrieving data? I'm very interested in
hearing your opinion on this one, we've had developers in the past rely
on an "Active" bit for rows in certain tables we use. For instance, an
operation location around the country, making it accesible to the
application via the active bit. I don't particularly like doing this
and have advised not doing it. Thanks for your time.
Mark
|||Thanks Adam,
But how the visibility helps me? Should client B(who is editing the record)
mark the record as invisible? What if client B crashes while editing and the
record remains invisible in table?
"Adam Machanic" <amachanic@.hotmail._removetoemail_.com> wrote in message
news:#t8hQQF5EHA.1976@.TK2MSFTNGP09.phx.gbl...
> One way to solve this is to never delete a row. Add a column called
> 'Visible' that will act as a boolean for the UI to display or not display
> the row. When a user 'deletes' a row, the row should really just be
marked
> as not visible. Then you can implement some logic (via a trigger) such
that[vbcol=seagreen]
> if a row is updated when it's marked 'not visible', it will be marked
> 'visible' again.
> --
> Adam Machanic
> SQL Server MVP
> http://www.sqljunkies.com/weblog/amachanic
> --
>
> "Leila" <Leilas@.hotpop.com> wrote in message
> news:eU2lWsE5EHA.1596@.tk2msftngp13.phx.gbl...
> that.
> the
Whereas
>
|||<myelton1@.Lincare.com> wrote in message
news:1103302784.609659.76270@.z14g2000cwz.googlegro ups.com...
> way. My question is about spliting the table by using the Visible bit
> and querying on the table later. Wouldn't you have to always use that
> bit on your Selects and therefore not having the most effecient "index"
> of sorts to use when you are retrieving data? I'm very interested in
> hearing your opinion on this one, we've had developers in the past rely
> on an "Active" bit for rows in certain tables we use. For instance, an
> operation location around the country, making it accesible to the
> application via the active bit. I don't particularly like doing this
> and have advised not doing it. Thanks for your time.
Yes, you would always have to use that column in your selects. Note, it
doesn't necessarily have to be a BIT. A lot of developers prefer CHAR(1)
NOT NULL CHECK (Visible IN 'Y', 'N'). Whether it will cause problems? It
depends on how many deleted columns there are, how selective the rest of the
columns in the queries are, etc. I probably wouldn't even bother adding it
to any indexes (except maybe covering indexes), as SQL Server can seek using
the keys from the queries and then filter the rows where Visible = 'N' quite
easily. Again, though, it depends. As always, test heavily
Another option is to store PKs from deleted rows in another table and
then you can query like:
SELECT *
FROM YourTable
WHERE NOT EXISTS
(SELECT *
FROM YourTableDeletedRows T1
WHERE T1.PK = YourTable.PK)
I don't know how that will perform, but it may solve the issue if you're
getting index scans due to the 'boolean' column.
Adam Machanic
SQL Server MVP
http://www.sqljunkies.com/weblog/amachanic
|||Thanks,
Actually I thought about that but I don't know what to do if the client
crashes? Because the PK remains in that table and no longer will be
deleted..
<myelton1@.Lincare.com> wrote in message
news:1103300244.952647.179750@.z14g2000cwz.googlegr oups.com...
> I'm not sure what you mean by 'our clients are disconnected' but you
> could throw the Primary Key value of the row being edited into a table.
> A "this row is locked" table of sorts. Then any other user reading
> that row you require your application to check your Lock table for the
> Primary key value, if it is found then you return a message saying "you
> can't delete this record, it's being edited by another user." Or
> something like that, we've done that for our OLTP system in the past.
>
|||"Leila" <Leilas@.hotpop.com> wrote in message
news:ukmR7uF5EHA.3120@.TK2MSFTNGP12.phx.gbl...
> Thanks Adam,
> But how the visibility helps me? Should client B(who is editing the
record)
> mark the record as invisible? What if client B crashes while editing and
the
> record remains invisible in table?
ClientA is looking at the record.
ClientB is editing the record.
ClientA hits the "delete" button on the UI. This flips the "Visible"
column on the row.
ClientB submits the edits...
And now the "Visible" column gets flipped back.
You will probably also want to investigate how to periodically delete
all of the rows marked "not visible" so that your table isn't full of too
much unused legacy data.
Adam Machanic
SQL Server MVP
http://www.sqljunkies.com/weblog/amachanic
|||Leila wrote:
> Thanks Adam,
> But how the visibility helps me? Should client B(who is editing the record)
> mark the record as invisible? What if client B crashes while editing and the
> record remains invisible in table?
The real problem here is that you didn't provide much real detail so
people have to make guesses.
However, you can implement date/time stamps to track when rows are
"checked out" and create an interface to override checked out rows if
there is a crash.
But, you said your clients are "disconnected". If that is indeed the
case, and both clients can have the same data locally, how do you expect
ANY kind of concurrency checking to take place? Your design doesn't
really allow for it. One solution that does come to mind is that you
create a system to manage changes/deletes each time a client reconnects
to the source data.
But, back to your lack of problem description. When you say that A
cannot delete while B is editing, is that ONLY during the exact time
that B is editing? Honestly, why does it matter? If you're going to let
A delete the data anyway, you're not gaining much by adding in this
check. In fact, you should create a system so that if A does in fact
delete a row while B is editing it, and B then saves the data, they are
notified that the data was deleted by another client and then allow be
to with discard their data (and thus totally deleting the data) or
optionally read the data back to the database. Imperfect solution but it
sounds like you have an imperfect design :D
You may want to post some additional information about the rules that
govern the whole deletion/editing process. Like, how often do the client
connect to the database to sync their data sets? What happens when two
clients edit the same data, who takes precedence? How do you handle
duplicate data? etc.
Zach

> "Adam Machanic" <amachanic@.hotmail._removetoemail_.com> wrote in message
> news:#t8hQQF5EHA.1976@.TK2MSFTNGP09.phx.gbl...
>
> marked
>
> that
>
> Whereas
>
>
|||If client B crashes, it cannot submit the changes and make the record
visible again. I mean the record will remain invisible
"Adam Machanic" <amachanic@.hotmail._removetoemail_.com> wrote in message
news:O5#E6xF5EHA.1976@.TK2MSFTNGP09.phx.gbl...
> "Leila" <Leilas@.hotpop.com> wrote in message
> news:ukmR7uF5EHA.3120@.TK2MSFTNGP12.phx.gbl...
> record)
> the
>
> ClientA is looking at the record.
> ClientB is editing the record.
> ClientA hits the "delete" button on the UI. This flips the "Visible"
> column on the row.
> ClientB submits the edits...
> And now the "Visible" column gets flipped back.
> You will probably also want to investigate how to periodically delete
> all of the rows marked "not visible" so that your table isn't full of too
> much unused legacy data.
>
> --
> Adam Machanic
> SQL Server MVP
> http://www.sqljunkies.com/weblog/amachanic
> --
>