March 1, 2012 at 11:39 pm
Comments posted to this topic are about the item Service Broker Transactions
March 2, 2012 at 12:13 am
Good question. Thanks.
Although I had never used BrokerSend before, I had done something similar on linked servers, ending up in the same error.
March 2, 2012 at 1:30 am
Good question!
Explained situation is known as "Uncommitable transaction".
MS SQL 2008 MCITP x 3
MS SQL 2012 MCSE x 2
March 2, 2012 at 4:32 am
Interesting question. I haven't a clue in this area of SQL Server, but it looked like a choice between option 1 and option 3 (option 4 had to be a joke - if it were that it would be famous, but it isn't famous so it isn't that; and option 2 seemed too silly for words). Option 1 was less bizarre, so I chose that and got it wrong.
The trouble is that even with the explanation and a bit of background reading, I still don't understand it; so obviously I have a lot more reading to do. I guess that means that this QoTD will result in a fair chunk of learning, so it must be a good question.
Tom
March 2, 2012 at 7:51 am
Yes, option 4 is a joke.
This is an uncommittable transaction, you can see outlined in the linked BOL on TRY CATCH with Transactions. I ran into the issue because of an error in a production situation where the massively complicated stored procedure started throwing the "unable to write" exception about 1 time per week. Fortunately a coworker managed to reproduce in house and we were able to identify that the Dialog ID (or conversation id) was what was invalid and causing everything else.
Working with Service Broker and XML data types can be VERY tricky when dealing with transactions as everything is a severity 16 error which causes the Uncommittable Transaction condition.
March 2, 2012 at 8:03 am
So, how would you fix the posted code so that the uncommittable transaction message isn't reported?
I'm curious which COMMIT statement is causing the error. There's a COMMIT statement after the CATCH block inside the proc, and also a COMMIT in the outer transaction.
I suppose one (or both) of these should check XACT_STATE() before executing?
March 2, 2012 at 8:16 am
I also don't have any experience in this part of sql but like I Tom I kind of guesses it would be 1 or 3. However answer #4 was just way too funny so I had to pick that to make sure that at least 1 person did. 😀
Interesting question about a topic I am totally unfamiliar with. Will have to come back and read on this when I get a chance.
_______________________________________________________________
Need help? Help us help you.
Read the article at http://www.sqlservercentral.com/articles/Best+Practices/61537/ for best practices on asking questions.
Need to split a string? Try Jeff Modens splitter http://www.sqlservercentral.com/articles/Tally+Table/72993/.
Cross Tabs and Pivots, Part 1 – Converting Rows to Columns - http://www.sqlservercentral.com/articles/T-SQL/63681/
Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs - http://www.sqlservercentral.com/articles/Crosstab/65048/
Understanding and Using APPLY (Part 1) - http://www.sqlservercentral.com/articles/APPLY/69953/
Understanding and Using APPLY (Part 2) - http://www.sqlservercentral.com/articles/APPLY/69954/
March 2, 2012 at 8:38 am
Interesting question. I guessed ... and guessed wrong
____________________________________________________
Deja View - The strange feeling that somewhere, sometime you've optimised this query before
How to get the best help on a forum
http://www.sqlservercentral.com/articles/Best+Practices/61537March 2, 2012 at 9:05 am
Stephanie Giovannini (3/2/2012)
So, how would you fix the posted code so that the uncommittable transaction message isn't reported?I'm curious which COMMIT statement is causing the error. There's a COMMIT statement after the CATCH block inside the proc, and also a COMMIT in the outer transaction.
I suppose one (or both) of these should check XACT_STATE() before executing?
The easiest method to fix the error that prompted this question is to check for the Dialog ID (or Conversation ID) in the sys.conversation_endpoints system table (or view?). The error is not at a commit statement, rather at the INSERT INTO dbo.[BrokerErrors] is where it throws the Severity 16, unable to perform operations that write to the log.
Order of Exceptions:
1. SEND exception (Severity 16)
2. INSERT INTO (Severity 16) <-- this is returned to the calling SP/App, aka answer 3
March 2, 2012 at 9:18 am
Thanks for the question.
Jason...AKA CirqueDeSQLeil
_______________________________________________
I have given a name to my pain...MCM SQL Server, MVP
SQL RNNR
Posting Performance Based Questions - Gail Shaw[/url]
Learn Extended Events
March 2, 2012 at 10:15 am
Tough question for those of us who don't have experience on this area. I didn't understand quite well the code, nor the papers I found, so i had to basically guess... and got it wrong. 🙁
"El" Jerry
March 2, 2012 at 10:18 am
Thanks for the question. I don't have any experience in this area either.
March 2, 2012 at 11:27 am
Interesting question. Thanks 🙂
Service Broker is a facinating technology. I've used it for simple data transfer between servers, to maintaining complex full text indexes (single FT index based on data from multiple tables) and maintaining ACL inheritance in our document management system. The async nature of service brokers opens up endless possibilities. I just LOVE it.
March 2, 2012 at 12:19 pm
venoym (3/2/2012)
Stephanie Giovannini (3/2/2012)
So, how would you fix the posted code so that the uncommittable transaction message isn't reported?I'm curious which COMMIT statement is causing the error. There's a COMMIT statement after the CATCH block inside the proc, and also a COMMIT in the outer transaction.
I suppose one (or both) of these should check XACT_STATE() before executing?
The easiest method to fix the error that prompted this question is to check for the Dialog ID (or Conversation ID) in the sys.conversation_endpoints system table (or view?). The error is not at a commit statement, rather at the INSERT INTO dbo.[BrokerErrors] is where it throws the Severity 16, unable to perform operations that write to the log.
Order of Exceptions:
1. SEND exception (Severity 16)
2. INSERT INTO (Severity 16) <-- this is returned to the calling SP/App, aka answer 3
Actually, it looks like there are two errors. The first error is the nonexistent dialog id. The second error is attempting to commit an uncommittable transaction after the first error occurs.
How would the code look if the dialog id error may still occur, but the error handing is fixed?
I played around a bit, and realized the problem with the uncommittable transaction is not related to Service Broker itself. The following code, based on the order of transactional statements in the procedure, causes the same transaction error:
create table #errorlog (error nvarchar(50))
set xact_abort on
begin transaction
begin try
select 3 / 0
end try
begin catch
insert #errorlog values('error')
end catch
commit
The following structure works:
create table #errorlog (error nvarchar(50))
set xact_abort on
begin transaction
begin try
select 3 / 0
commit
end try
begin catch
rollback
insert #errorlog values('error')
end catch
However, in this case the calling code also has a transaction. Putting additional begin/commit around the code results in "The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION."
The SQL that calls the procedure needs to check before committing. Like so:
create table #errorlog (error nvarchar(50))
set xact_abort on
begin transaction
-- enter procedure
begin transaction
begin try
select 3 / 0
commit
end try
begin catch
rollback
insert #errorlog values('error')
end catch
-- exit procedure
if XACT_STATE() = 1 commit
March 2, 2012 at 1:03 pm
Stephanie Giovannini (3/2/2012)
Actually, it looks like there are two errors. The first error is the nonexistent dialog id. The second error is attempting to commit an uncommittable transaction after the first error occurs.
How would the code look if the dialog id error may still occur, but the error handing is fixed?
I played around a bit, and realized the problem with the uncommittable transaction is not related to Service Broker itself. The following code, based on the order of transactional statements in the procedure, causes the same transaction error:
create table #errorlog (error nvarchar(50))
set xact_abort on
begin transaction
begin try
select 3 / 0
end try
begin catch
insert #errorlog values('error')
end catch
commit
The following structure works:
create table #errorlog (error nvarchar(50))
set xact_abort on
begin transaction
begin try
select 3 / 0
commit
end try
begin catch
rollback
insert #errorlog values('error')
end catch
However, in this case the calling code also has a transaction. Putting additional begin/commit around the code results in "The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION."
The SQL that calls the procedure needs to check before committing. Like so:
create table #errorlog (error nvarchar(50))
set xact_abort on
begin transaction
-- enter procedure
begin transaction
begin try
select 3 / 0
commit
end try
begin catch
rollback
insert #errorlog values('error')
end catch
-- exit procedure
if XACT_STATE() = 1 commit
Stephanie, I do like where you are going. I haven't tried exactly what you've done, mainly because I'm several levels deep (the QotD is a trivial example) in nested procedure calls, and in the enterprise environment I'm in I don't have the ability to modify everything that uses this in the manner you've said. It's probably an avenue to explore to prevent nasty messages in processing that I will investigate soon.
I will throw my 2 cents behind what really needs to be allowed is the ability to do a Checkpoint before the TRY...CATCH and then roll back to it on an exception. It actually makes sense to do that in cases where you are accessing non-local DB items (such as service broker, filesystem, etc.) that way you can do exception handling/logging but maintain the business logic/process. Sadly, this is not available and all Severity 16 exceptions result in an uncomittable transaction.
Viewing 15 posts - 1 through 15 (of 21 total)
You must be logged in to reply to this topic. Login to reply