Showing posts with label based. Show all posts
Showing posts with label based. Show all posts

Monday, March 26, 2012

Poison Messages - 5 times's a charm

Hello again,
I have some poison message detection in place, based on the BOL sample. My problem is that after the 5th message retry my queue goes down - that is the fifth retry on any message. In actuallity, the first message is retried 3 times and it is taken off the queue [for real], the second message comes in and on the second retry - pooof - the queue is down.

I though the poison mechanism should work on a per message basis. It there a setting for the queue I missed? Is my only chance for to fix this: re-enable the queue upon BROKER_QUEUE_DISABLED event notification?

Thanks,

Lubomir

The poison message counter is based on RECEIVE verbs being rolled back. So five RECEIVEs rolled back in a row and your queue is disabled. The number of individual messages received/rolled back is irelevant. Any RECEIVE commited will reset the counter to 0.

Unfortunately this is not configurable in any way, you only have the BROKER_QUEUE_DISABLED notification as a way to react.

HTH,
~ Remus

|||Sorry to unmark the answer. I want to have a check after a ROLLBACK on the queue to see if the queue is DISBLED? i just could not figure out the TSQL for that?

if QUEUE is disabled
ALTER [dbo].[ProcessQueue] WITH STATUS = ON

EVENT NOTIFICATION does not allow for a direct TSQL exectuion from what I have seen so far, getting the status of queue and acting on it is not straight forward.

Thanks,

Lubomir|||

Event notifications are deliverd through normal Service Broker messages, so the way to execute TSQL on an event notification is to have an activated procedure on the queue that receives the event notification and execute the TSQL in it. The name of the queue being disabled will be part of the notification message.

To get the queue status use the is_receive_enabled or is_enqueue_enabled in sys.service_queues:

if (1 = (select is_receive_enabled from sys.service_queues where name = '...'))
begin
alter queue [...] with status = on;
end

Trying to enable back the queue from the activated procedure, after the rollback, however, will probably not work, because the queue disabling mechanism is asynchronous so you're verification check query will sometimes get the status disabled, sometimes not.

I recommend you try to avoid the rollbacks in the first place. If you try to incorporate rollback in the logic then you might hit a real poison message situation in production and you system will halt to a grind, spining on this one message.

HTH,
~ Remus

|||Thank you for the reply Remus,
My logic does take out the message after 3 retries, so I figure I should be safe, no?
I perform the rollbacks to freshly process the message in the hope conditions that caused the failure have disappeared - slim chance on that and probably something that will cause more trouble than good.
What do yo think?

Lubomir|||

If what you're looking for is a retry mechanism, then you should probably consider dialog timers, perhaps used in a fashion similar to this:

BEGIN TRANSACTION;
WAITFOR(RECEIVE ... FROM ...), TIMEOUT ...;
IF MESSAGE TYPE IS 'UNRELIABLE REQUEST'
BEGIN
INSERT REQUEST MESSAGE BODY INTO USER TABLE;
BEGIN DIALOG TIMER @.someretrytimeout;
END
ELSE IF MESSAGE TYPE IS 'TIMER'
BEGIN
SELECT REQUEST MESSAGE BODY FROM USER TABLE;
-- Re-arm the timer
BEGIN DIALOG TIMER @.someretrytimeout;
END
COMMIT;

DO UNRELIABLE WORK HERE BASED ON THE RECEIVED/SELECTED REQUEST

IF SUCCEEDED
BEGIN
BEGIN TRANSACTION
SEND BACK RESPONSE;
-- RESET TIMER TO 0 (or END CONVERSATION, as appropiate)
BEGIN DIALOG TIMER 0;
COMMIT
END

This way you separate the error prone processing outside the transaction and you don't need to rollback on failure. Also, you get to controll the retry details: number of retries, time between retries, backout policy etc.

HTH,
~ Remus

Friday, March 23, 2012

Point in Time Restore Part II

In the hereunder written message I talk about point in time restore.
It is now based upon the fact that there are no hardware problems or what so
ever.
I just would like to roll back to a situation of some time (minutes, hours
or what ever) ago.

Used to the ingres database a point in time restore can take place UP to
any, any, any time since the last FULL backup. (any time up to now !!!)

I can't understand why a point in time restore can only be done based upon
transaction log backups. The current transaction log is also available in my
opinion. (Turn off the power, turn on the power and you will notice that the
automatic recovery is based upon this transaction log file; so in that case
this file is used)

That's what my question is about. Is it correct that a point in time restore
in a SQL server environment can only be done up to the last transaction log
backup.

Bye

Arno de Jong,
The Netherlands.A.M. de Jong (arnojo@.wxs.nl) writes:
> Used to the ingres database a point in time restore can take place UP to
> any, any, any time since the last FULL backup. (any time up to now !!!)
> I can't understand why a point in time restore can only be done based
> upon transaction log backups. The current transaction log is also
> available in my opinion. (Turn off the power, turn on the power and you
> will notice that the automatic recovery is based upon this transaction
> log file; so in that case this file is used)
> That's what my question is about. Is it correct that a point in time
> restore in a SQL server environment can only be done up to the last
> transaction log backup.

Just because Ingress works in one way, there is no requirement for MS
SQL Server to work in that way too.

In SQL Server you need a transaction-log backup to do a point-in-time
restore, but since you can backup the transaction log at any point,
this is not any serious restriction.

I should add here that you must be running full or bulk_logged recovery
mode to have availability to point-in-time restore. With simple recovery
mode, this feature is not available.

In the case you want to undo a fatal SQL statement like an UPDATE without
a WHERE clause, you may be interested in exploring the third-party tool
Log Explorer from Lumigent, check out www.lumigent.com.

--
Erland Sommarskog, SQL Server MVP, sommar@.algonet.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp

Tuesday, March 20, 2012

PLS. HELP. SQL NEWBIE

hello all. please tell me why the following update staement doesn't
work.

what i want to do is update tblmaster.mcol2 based on the value of
tblheader.hcol2

hcol2 values:
1 = add ( tbldetails.dcol3 * tbldetails.dcol4 ) to mcol2
2 = subtract ( tbldetails.dcol3 * tbldetails.dcol4 ) from mcol2

i tried it using query analyzer but it still adds even though the
value of hcol2 is 2.

create table tblmaster ( mcol1 nvarchar(3),
mcol2 float )

insert into tblmaster values ('001', 1)
insert into tblmaster values ('002', 1)
insert into tblmaster values ('003', 1)
insert into tblmaster values ('004', 1)
insert into tblmaster values ('005', 1)

create table tblheader ( hcol1 int,
hcol2 smallint )

create table tbldetails ( dcol1 int,
dcol2 nvarchar(3),
dcol3 float,
dcol4 float )

insert into tblheader values (1, 1)
insert into tblheader values (2, 1)
insert into tblheader values (3, 2)

insert into tbldetails values ( 1, '001', 1, 10 )
insert into tbldetails values ( 1, '002', 1, 10 )

insert into tbldetails values ( 2, '001', 1, 10 )
insert into tbldetails values ( 2, '003', 2, 10 )

insert into tbldetails values ( 3, '004', 1, 10 )
insert into tbldetails values ( 3, '005', 2, 10 )

declare @.lo as int
declare @.hi as int

set @.lo = 1
set @.hi = 3

UPDATE tblmaster
SETmcol2 =
CASE h.hcol2
WHEN 1 THEN mcol2 + ( ABS( d.dcol3 ) * ABS( d.dcol4 ) )
WHEN 2 THEN mcol2 - ( ABS( d.dcol3 ) * ABS( d.dcol4 ) )
END
FROM tblmaster t, tblheader h, tbldetails d
WHERE t.mcol1 = d.dcol2 AND h.hcol1 BETWEEN @.lo and @.hi

select * from tblmaster

TIA,

diegoHi Rey

It is not clear how your tables are actually related but you may want to try
something like:

"Rey Guerrero" <rey_guerrero@.hotmail.com> wrote in message
news:d401c59b.0412220652.54dfa7cb@.posting.google.c om...
> hello all. please tell me why the following update staement doesn't
> work.
> what i want to do is update tblmaster.mcol2 based on the value of
> tblheader.hcol2
> hcol2 values:
> 1 = add ( tbldetails.dcol3 * tbldetails.dcol4 ) to mcol2
> 2 = subtract ( tbldetails.dcol3 * tbldetails.dcol4 ) from mcol2
> i tried it using query analyzer but it still adds even though the
> value of hcol2 is 2.
>
> create table tblmaster ( mcol1 nvarchar(3),
> mcol2 float )
> insert into tblmaster values ('001', 1)
> insert into tblmaster values ('002', 1)
> insert into tblmaster values ('003', 1)
> insert into tblmaster values ('004', 1)
> insert into tblmaster values ('005', 1)
> create table tblheader ( hcol1 int,
> hcol2 smallint )
> create table tbldetails ( dcol1 int,
> dcol2 nvarchar(3),
> dcol3 float,
> dcol4 float )
> insert into tblheader values (1, 1)
> insert into tblheader values (2, 1)
> insert into tblheader values (3, 2)
> insert into tbldetails values ( 1, '001', 1, 10 )
> insert into tbldetails values ( 1, '002', 1, 10 )
> insert into tbldetails values ( 2, '001', 1, 10 )
> insert into tbldetails values ( 2, '003', 2, 10 )
> insert into tbldetails values ( 3, '004', 1, 10 )
> insert into tbldetails values ( 3, '005', 2, 10 )
> declare @.lo as int
> declare @.hi as int
> set @.lo = 1
> set @.hi = 3
> UPDATE tblmaster
> SET mcol2 =
> CASE h.hcol2
> WHEN 1 THEN mcol2 + ( ABS( d.dcol3 ) * ABS( d.dcol4 ) )
> WHEN 2 THEN mcol2 - ( ABS( d.dcol3 ) * ABS( d.dcol4 ) )
> END
> FROM tblmaster t, tblheader h, tbldetails d
> WHERE t.mcol1 = d.dcol2 AND h.hcol1 BETWEEN @.lo and @.hi
> select * from tblmaster
> TIA,
> diego|||Hi Rey

It is not clear how your tables are actually related but you may want to try
something like:

UPDATE t
SET mcol2 =
CASE h.hcol2
WHEN 1 THEN mcol2 + ( ABS( d.dcol3 ) * ABS( d.dcol4 ) )
WHEN 2 THEN mcol2 - ( ABS( d.dcol3 ) * ABS( d.dcol4 ) )
END
FROM tblmaster t
JOIN tbldetails d ON t.mcol1 = d.dcol2
JOIN tblheader h ON h.hcol1 = d.dcol1
WHERE h.hcol1 BETWEEN @.lo and @.hi

As tblmaster has is a one to many relationship with tbldetails you will have
to either restrict which rows match or use an aggregate

UPDATE t
SET mcol2 = mcol2 + val
FROM tblmaster t
JOIN ( SELECT d.dcol2, SUM( CASE WHEN h.col2 = 1 THEN d.dcol3 * dcol4
ELSE -1 * dcol3 * dcol4 END ) as val
FROM tbldetails d
JOIN tblheader h ON h.hcol1 = d.dcol1
WHERE h.hcol1 BETWEEN @.lo and @.hi GROUP BY d.dcol2 ) d ON t.mcol1 =
d.dcol2

John

"Rey Guerrero" <rey_guerrero@.hotmail.com> wrote in message
news:d401c59b.0412220652.54dfa7cb@.posting.google.c om...
> hello all. please tell me why the following update staement doesn't
> work.
> what i want to do is update tblmaster.mcol2 based on the value of
> tblheader.hcol2
> hcol2 values:
> 1 = add ( tbldetails.dcol3 * tbldetails.dcol4 ) to mcol2
> 2 = subtract ( tbldetails.dcol3 * tbldetails.dcol4 ) from mcol2
> i tried it using query analyzer but it still adds even though the
> value of hcol2 is 2.
>
> create table tblmaster ( mcol1 nvarchar(3),
> mcol2 float )
> insert into tblmaster values ('001', 1)
> insert into tblmaster values ('002', 1)
> insert into tblmaster values ('003', 1)
> insert into tblmaster values ('004', 1)
> insert into tblmaster values ('005', 1)
> create table tblheader ( hcol1 int,
> hcol2 smallint )
> create table tbldetails ( dcol1 int,
> dcol2 nvarchar(3),
> dcol3 float,
> dcol4 float )
> insert into tblheader values (1, 1)
> insert into tblheader values (2, 1)
> insert into tblheader values (3, 2)
> insert into tbldetails values ( 1, '001', 1, 10 )
> insert into tbldetails values ( 1, '002', 1, 10 )
> insert into tbldetails values ( 2, '001', 1, 10 )
> insert into tbldetails values ( 2, '003', 2, 10 )
> insert into tbldetails values ( 3, '004', 1, 10 )
> insert into tbldetails values ( 3, '005', 2, 10 )
> declare @.lo as int
> declare @.hi as int
> set @.lo = 1
> set @.hi = 3
> UPDATE tblmaster
> SET mcol2 =
> CASE h.hcol2
> WHEN 1 THEN mcol2 + ( ABS( d.dcol3 ) * ABS( d.dcol4 ) )
> WHEN 2 THEN mcol2 - ( ABS( d.dcol3 ) * ABS( d.dcol4 ) )
> END
> FROM tblmaster t, tblheader h, tbldetails d
> WHERE t.mcol1 = d.dcol2 AND h.hcol1 BETWEEN @.lo and @.hi
> select * from tblmaster
> TIA,
> diego

Saturday, February 25, 2012

Please help: Create View

Hi Gurus,
I'm a beginner. Would you please tell me if it's possible to create a view
having a calcuated column based on the condition of the column on the sql
table.

create view vwImaging AS
select
EmpID, LastName, FirstName, EmpTag = 'Act' if

FROM tblPerPay
I have a table EMP:
SSN (char 9)

A view giving a formatted SSN (XXX-XX-XXXX,) a

--
Message posted via http://www.sqlmonster.comSorry, I press the "Post Message" by accident while editing the message.

Here is question again: Is it possible to create a view having a column
based on the value of a given column on the sql table.

create view LookUp AS
select
EmpID,
LastName,
FirstName,
EmpTag = 'Act' (if tblEmp.TermDate is Null)
EmpTag = 'Inact' (if tblEmp.TermDate not Null)
from tblEmp

I don't know the syntax of the last 2 columns. TermDate is the termination
date in tblEmp.

Any help will be greatly appreciated.
Thanks in advance
TTran

--
Message posted via http://www.sqlmonster.com|||"T Tran via SQLMonster.com" <forum@.SQLMonster.com> wrote in message
news:c015ee60567f4767934b62908ec07144@.SQLMonster.c om...
> Sorry, I press the "Post Message" by accident while editing the message.
> Here is question again: Is it possible to create a view having a column
> based on the value of a given column on the sql table.
> create view LookUp AS
> select
> EmpID,
> LastName,
> FirstName,
> EmpTag = 'Act' (if tblEmp.TermDate is Null)
> EmpTag = 'Inact' (if tblEmp.TermDate not Null)
> from tblEmp
> I don't know the syntax of the last 2 columns. TermDate is the termination
> date in tblEmp.
> Any help will be greatly appreciated.
> Thanks in advance
> TTran
> --
> Message posted via http://www.sqlmonster.com

Check out CASE in Books Online. Do you need two EmpTag columns? If Act/Inact
is a flag, it may make more sense to use only one column:

create view LookUp AS
select
EmpID,
LastName,
FirstName,
EmpTag = case when TermDate is Null then 'Act' else 'Inact' end
from
tblEmp

But if you do need separate columns, then try this (it's usually not a good
idea to return multiple columns with the same name):

create view LookUp AS
select
EmpID,
LastName,
FirstName,
EmpTagAct = case when TermDate is null then 'Act' else '-' end,
EmpTagInact = case when TermDate is not null then 'Inact' else '-' end
from
tblEmp

Simon|||Since you are learning SQL, you might want to start by learning
ISO-11179 rules for names and the Standard SQL syntax for aliases. A
CASE expression will handle this:

CREATE VIEW PersonnelStatus (ssn, last_name, first_name,
employment_status)
AS
SELECT ssn, last_name, first_name,
CASE (WHEN term_date IS NULL
THEN 'inactive'
ELSE 'active ' END
FROM Personnel;

The equal sign is local dialect; the AS operator is Standard. Use
collective or plural nouns for table names; never put a prefix on a
data element to tell us how it is *physically* stored. This is really
silly in SQL, since there is only one data structure.

I have a book on SQL PROGRAMMING STYLE due out the middle of this year
that might be of some help to you.