Showing posts with label transactions. Show all posts
Showing posts with label transactions. Show all posts

Sunday, March 11, 2012

Blocking Transactions

Hi Guys...

Another issue, this time regarding transactions.
It seems that blocking occurs very often when processes are being put into transactions.

For example, I have two tables, tableA and tableB.

I create a sequence container, and inside, i put in two process.
1. Execute SQL - this to insert data into tableA.
2. Data Flow Task - move data from tableA to tableB
Set the sequence container transactions to required.

When I run the package, it always get stuck at process 2.
I tried running the SP_WHO2 command, and it shows that its suspended, being blocked by id "-2".
Any idea to solve this?

Thanks.

Cheers,

Ryan TanSince the transaction is active when #2 is running, #1 probably gets X locks that prevent #2 from getting data. Looks like you either need to commit the transaction after #1 is done, or change the connection manager to allow a less severe isolation level.

blocking issue.

I have "scenario 2" blocking issue. the process is sleeping and open transac
tions is 1 or more.
However the command that was run was a prodedure that has "No Begin Transact
ion, or rollback or commit."
Any ideas?
I don't understand how the open transactions can be greater then zero.You are probably have SET IMPLICIT_TRANSACTIONS ON .
Andrew J. Kelly SQL MVP
"mannie" <anonymous@.discussions.microsoft.com> wrote in message
news:5F627C7E-59AD-4232-B80D-588E58B932C0@.microsoft.com...
> I have "scenario 2" blocking issue. the process is sleeping and open
transactions is 1 or more.
> However the command that was run was a prodedure that has "No Begin
Transaction, or rollback or commit."
> Any ideas?
> I don't understand how the open transactions can be greater then zero.|||I have not. Perhapes the default mode has been set in some configuration at
the server level. Is this possible?|||Yes, the default for a lot of drivers is to set implicit transactions on.
You can run profiler and make sure to include the Existing connections event
to see what gets set.
Andrew J. Kelly SQL MVP
"mannie" <anonymous@.discussions.microsoft.com> wrote in message
news:A558E87B-FA4C-4FE4-B4D1-15D745B50F17@.microsoft.com...
> I have not. Perhapes the default mode has been set in some configuration
at the server level. Is this possible?

Thursday, March 8, 2012

Blocking and Transactions OK?

I'm wondering if I'm doing this right. Wondering about the transactions
and error handling. (Do I even need to put BEGIN TRANSACTION AND
COMMIT TRANSACTION in there?)

I think that this sproc is causing occasional blocking:

Alter Procedure sprocINSERTSTUFF
@.Col1Data int = Null,
@.Col2Data nvarchar(255) = Null,
@.Col3Data ntext = Null,
@.UniqueID int OUTPUT

AS

set nocount on
set xact_abort on

DECLARE @.err int
DECLARE @.ServerDate DateTime
SELECT @.ServerDate = GETUTCDATE()

BEGIN TRANSACTION

INSERT INTO
tblStuff (Col1, Col2, Col3, DateCreated, etc.)
VALUES
(@.Col1Data, @.Col2Data, @.Col3Data, @.ServerDate, etc.)

SELECT @.err = @.@.error IF @.err <> 0 BEGIN ROLLBACK TRANSACTION RETURN
@.err END

SELECT @.UniqueID = SCOPE_IDENTITY()

COMMIT TRANSACTION

BEGIN TRANSACTION

INSERT INTO
tblMoreStuff (UniqueID, DateCreated, Col1, Col2, Col3)
Values
(@.UniqueID, @.ServerDate, @.Col1Data, @.Col2Data, 'Text Label: ' +
isnull(Cast(@.Col3Data AS nvarchar(4000)),'<none>')

SELECT @.err = @.@.error IF @.err <> 0 BEGIN ROLLBACK TRANSACTION RETURN
@.err END

COMMIT TRANSACTION
SELECT @.err = @.@.error IF @.err <> 0 RETURN @.errlaurenq uantrell (laurenquantrell@.hotmail.com) writes:
> I'm wondering if I'm doing this right. Wondering about the transactions
> and error handling. (Do I even need to put BEGIN TRANSACTION AND
> COMMIT TRANSACTION in there?)

Depends on your business requirements. If it's OK that a row gets
inserter into tblStuff, but not any row in tblMoreStuff, you can take
it out entirely. If you want both rows or none of the rows inserted,
you should take out the COMMIT and the BEGIN in the middle, to make
it one single transaction.

> I think that this sproc is causing occasional blocking:

Since it's only two plain insert statements, that's a bit surprising.
But if there is a long-running trigger on one of the tables you could
get blocking.

> @.Col3Data ntext = Null,
>...
> 'Text Label: ' +
> isnull(Cast(@.Col3Data AS nvarchar(4000)),'<none>')
>...

What's the point with accepting an ntext parameter, if you truncate it
anyway?

--
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,
Thanks for your reply.

> @.Col3Data ntext = Null,
>...
> 'Text Label: ' +
> isnull(Cast(@.Col3Data AS nvarchar(4000)),'<none>')
>...

>What's the point with accepting an ntext parameter, if you truncate it anyway?

The second table is used to hold a history of changes to the first
table tblStuff and in this particular case it's not necessary (or
desirable) to have the unlimited text in any ntext column stored, so
it's truncated.|||I forgot to mention in my front end application (MS Access 2K) I use
the following:

On Error GoTo myErr:
' Execute the sproc that runs the Insert above
myErr:
CurrentProject.Connection.Execute "IF @.@.trancount > 0 ROLLBACK
TRANSACTION", , adExecuteNoRecords

I am wondering if this should be sufficient to not leave an open
transaction in the event of an error.|||laurenq uantrell (laurenquantrell@.hotmail.com) writes:
> I forgot to mention in my front end application (MS Access 2K) I use
> the following:
> On Error GoTo myErr:
> ' Execute the sproc that runs the Insert above
> myErr:
> CurrentProject.Connection.Execute "IF @.@.trancount > 0 ROLLBACK
> TRANSACTION", , adExecuteNoRecords
> I am wondering if this should be sufficient to not leave an open
> transaction in the event of an error.

In theory maybe. But good software practice is that every module
cleans up after itself, and does not rely on somebody else to do it.
Least of all one should trust an application that uses ADO.

Look at it this way: you have this handling in many stored procedures.
Maybe you happen to forget to insert it in some place. And you have
this handling in many places in your client code. Maybe you acceidently
leave it in some place. So keep a double safeguard.

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

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp|||>Look at it this way: you have this handling in many stored procedures.
>Maybe you happen to forget to insert it in some place. And you have
>this handling in many places in your client code. Maybe you acceidently
>leave it in some place. So keep a double safeguard.

I'm not sure what you'rer suggesting...

I thought that this would clear up any error in the sproc:

SELECT @.err = @.@.error IF @.err <> 0 BEGIN ROLLBACK TRANSACTION RETURN
@.err END

COMMIT TRANSACTION
SELECT @.err = @.@.error IF @.err <> 0 RETURN @.err

Are you suggesting I put:

IF @.@.trancount > 0 ROLLBACK TRANSACTION

inthe sproc as well and not check for that in the front-end
application?|||>Look at it this way: you have this handling in many stored procedures.
>Maybe you happen to forget to insert it in some place. And you have
>this handling in many places in your client code. Maybe you acceidently
>leave it in some place. So keep a double safeguard.

I'm not sure what you'rer suggesting...

I thought that this would clear up any error in the sproc:

SELECT @.err = @.@.error IF @.err <> 0 BEGIN ROLLBACK TRANSACTION RETURN
@.err END

COMMIT TRANSACTION
SELECT @.err = @.@.error IF @.err <> 0 RETURN @.err

Are you suggesting I put:

IF @.@.trancount > 0 ROLLBACK TRANSACTION

inthe sproc as well and not check for that in the front-end
application?|||laurenq uantrell (laurenquantrell@.hotmail.com) writes:
>>Look at it this way: you have this handling in many stored procedures.
>>Maybe you happen to forget to insert it in some place. And you have
>>this handling in many places in your client code. Maybe you acceidently
>>leave it in some place. So keep a double safeguard.
> I'm not sure what you'rer suggesting...
> I thought that this would clear up any error in the sproc:
> SELECT @.err = @.@.error IF @.err <> 0 BEGIN ROLLBACK TRANSACTION RETURN
> @.err END
>
> COMMIT TRANSACTION
> SELECT @.err = @.@.error IF @.err <> 0 RETURN @.err
>
> Are you suggesting I put:
> IF @.@.trancount > 0 ROLLBACK TRANSACTION
> inthe sproc as well and not check for that in the front-end
> application?

So I'm suggesting that you should keep things as they are. (But make
sure that your transaction scope is the right one. The procedure
you posted seemed funny to me with a COMMIT in the middle.)

--
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. Thanks for the help and the good avice. The COMMIT in the
middle in this situation is because the first insert puts a new row of
data into a table, the second insert records the row/column info into a
row in a history table. In this situation, I want to be sure that the
new record is recorded in the primary data table even if the history is
not. If there is a failure on the second insert, I don't want to
rollback the first insert, even though the records might not end up in
sync (original and history) this would be corrected hopefully the next
time the record is updated.
I have considered and rejected using triggers for this purpose even
though that has been suggested.
Thanks again for your help in m understanding of how these things work!
lq|||laurenq uantrell (laurenquantrell@.hotmail.com) writes:
> Erland. Thanks for the help and the good avice. The COMMIT in the
> middle in this situation is because the first insert puts a new row of
> data into a table, the second insert records the row/column info into a
> row in a history table. In this situation, I want to be sure that the
> new record is recorded in the primary data table even if the history is
> not. If there is a failure on the second insert, I don't want to
> rollback the first insert, even though the records might not end up in
> sync (original and history) this would be corrected hopefully the next
> time the record is updated.

Good. I just wanted to make sure that it's on purpose.

(I remember a system I worked with looooong ago. There was a stored
proecdure that filled up a table, and it was one long transaction.
Unfortunately, it tended to fill up the transaction log. (This was
Sybase 4.x, no autogrow.) My colleagues found the fix - they inserted
some COMMIT/BEGIN. Oh well.)

> I have considered and rejected using triggers for this purpose even
> though that has been suggested.

Well, that would buy you a transaction for the current and history table.

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

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

Wednesday, March 7, 2012

Blocked transactions - how to identify the sql commands?

Hi SQLServer gurus :)

Just wondering if anyone can give me some info on how to find out the full syntax of the commands executed by the blocked and blocking SPID's in a locking situation.

Using sp_who or sp_who2 will give basic info on the blocked trans (such as DELETE, SELECT etc), but not the actual statement. The blocking spid's command is only showing AWAITING COMMAND.

Not really an urgent problem, but any suggestions appreciated!

Cheers,
MeganDBCC INPUTBUFFER
Displays the last statement sent from a client to Microsoft SQL Server.

Syntax
DBCC INPUTBUFFER (spid)

You can use this command to see what is the longest running command which may point to the transaction that is causing the blocking.

DBCC OPENTRAN
Displays information about the oldest active transaction and the oldest distributed and nondistributed replicated transactions, if any, within the specified database. Results are displayed only if there is an active transaction or if the database contains replication information. An informational message is displayed if there are no active transactions.

Syntax
DBCC OPENTRAN
( { 'database_name' | database_id} )
[ WITH TABLERESULTS
[ , NO_INFOMSGS ]
]|||Thanks for your response, achorozy.

Blocked Transactions

I was wanting to write a stored procedure which would identify queries which
are currently being blocked (spids 'blocked by' some other spid) when the
stored procedure is being run.
Is this possible? How do I go about figuring out how to do this?This query will get you the head of the blocking chain...
Declare @.SPID Varchar(500)
Select @.SPID = COALESCE(@.SPID + ',', '') + Cast(a.spid as varchar(20))
From master.dbo.sysprocesses a
where a.blocked = 0 and
a.spid IN (Select b.blocked From master.dbo.sysprocesses b Where b.blocked
!= 0)
Select @.SPID
--
HTH,
Vinod Kumar
MCSE, DBA, MCAD, MCSD
http://www.extremeexperts.com
Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinfo/productdoc/2000/books.asp
"Jim Heavey" <JimHeavey@.hotmail.com> wrote in message
news:O$u7BzDmDHA.2080@.TK2MSFTNGP10.phx.gbl...
> I was wanting to write a stored procedure which would identify queries
which
> are currently being blocked (spids 'blocked by' some other spid) when the
> stored procedure is being run.
> Is this possible? How do I go about figuring out how to do this?
>|||Heavey
Just as a starting point, I found that sysprocesses may be a good
place to start. I don't know what this does or anything, but it
looked relevant to the task:
> Select distinct spid, blocked, dbid from master..sysprocesses where blocked
>!= 0 for read only
>open DBA_lockinfo
>Declare @.spid varchar(5)
>Declare @.blocked varchar(5)
>Declare @.dbid varchar(10)
>Declare @.msg varchar (50)
>Declare @.event varchar(500)
>Declare @.event2 varchar(500)
>Create table #aux (EventType varchar(100), Parameters varchar(100),
>EventInfo varchar(500))
>Create table #aux2 (EventType varchar(100), Parameters varchar(100),
>EventInfo varchar(500))
>fetch next from DBA_lockinfo into @.spid, @.blocked, @.dbid
>While @.@.fetch_status = 0
>Begin
>Insert into #aux exec ('dbcc inputbuffer (' + @.spid + ')')
>Insert into #aux2 exec ('dbcc inputbuffer (' + @.blocked + ')')
>Set @.event = (select EventInfo from #aux)
>Set @.event2 = (select EventInfo from #aux2)
Good luck! Shoot me an email if you get a handle on it.
-Toby
On Tue, 21 Oct 2003 20:35:23 -0500, "Jim Heavey"
<JimHeavey@.hotmail.com> wrote:
>I was wanting to write a stored procedure which would identify queries which
>are currently being blocked (spids 'blocked by' some other spid) when the
>stored procedure is being run.
>Is this possible? How do I go about figuring out how to do this?
>|||Here is something I use. Show blocked spid and the path down to the one
causing all the waiting.
ALTER PROCEDURE dbo.ListBlockedTransactions
( @.ShowResults int = 1
)
as
SET NOCOUNT ON
-- created by M. Thomas Groszko
DECLARE BlockedSPIDSCursor CURSOR
FAST_FORWARD
FOR
SELECT BASE.SPID,
BASE.BLOCKED,
BASE.WAITTIME,
BASE.LASTWAITTYPE BLOCKED_LASTWAITTYPE,
CASE WHEN [CORPORATEDIRECTORY].[dbo].[ConcatenateName](SCD.LASTNAME,
SCD.FIRSTNAME, SCD.MIDDLENAME, SCD.PREFERREDNAME) IS NOT NULL
THEN rtrim(BASE.hostname) + '-' +
[CORPORATEDIRECTORY].[dbo].[ConcatenateName](SCD.LASTNAME, SCD.FIRSTNAME,
SCD.MIDDLENAME, SCD.PREFERREDNAME)
ELSE rtrim(BASE.hostname)
END BLOCKED_HOST
FROM SYSPROCESSES BASE
LEFT OUTER JOIN PCDB.dbo.PC PCBASE ON (BASE.hostname = PCBASE.MACHINEID)
LEFT OUTER JOIN PCDB.DBO.PERSON PERSONBASE ON (PCBASE.PERSONID =PERSONBASE.PERSONID)
LEFT JOIN CORPORATEDIRECTORY.dbo.PERSON SCD ON (PERSONBASE.CDID =SCD.PERSONID)
WHERE BASE.BLOCKED <> 0
ORDER BY BASE.last_batch DESC
FOR READ ONLY
DECLARE @.SampleTime DATETIME
SET @.SampleTime = GETDATE()
DECLARE @.BLOCKED_SPID INT
DECLARE @.BLOCKED_BLOCKEDBY INT
DECLARE @.BLOCKED_WAITTIME INT
DECLARE @.BLOCKED_LASTWAITTYPE VARCHAR(32)
DECLARE @.BLOCKED_HOST VARCHAR(255)
OPEN BlockedSPIDSCursor
FETCH BlockedSPIDSCursor INTO
@.BLOCKED_SPID,
@.BLOCKED_BLOCKEDBY,
@.BLOCKED_WAITTIME,
@.BLOCKED_LASTWAITTYPE,
@.BLOCKED_HOST
WHILE @.@.FETCH_STATUS = 0 -- while fetch returns a row
BEGIN
EXEC dbo.ShowBlockingSPID @.SampleTime, @.BLOCKED_BLOCKEDBY, 1
FETCH BlockedSPIDSCursor INTO
@.BLOCKED_SPID,
@.BLOCKED_BLOCKEDBY,
@.BLOCKED_WAITTIME,
@.BLOCKED_LASTWAITTYPE,
@.BLOCKED_HOST
END
CLOSE BlockedSPIDSCursor
DEALLOCATE BlockedSPIDSCursor
RETURN 0
go
ALTER PROCEDURE dbo.ShowBlockingSPID
( @.SampleTime DATETIME,
@.BlockingSPID int,
@.NestLevel int
)
as
SET NOCOUNT ON
-- created by M. Thomas Groszko
DECLARE @.BLOCKING_SPID INT
DECLARE @.BLOCKING_BLOCKEDBY INT
DECLARE @.BLOCKING_WAITTIME INT
DECLARE @.BLOCKING_LASTWAITTYPE VARCHAR(32)
DECLARE @.BLOCKING_HOST VARCHAR(255)
DECLARE @.NESTNEXTLEVEL INT
SELECT @.BLOCKING_SPID = BLOCKING.SPID,
@.BLOCKING_BLOCKEDBY = BLOCKING.BLOCKED,
@.BLOCKING_WAITTIME = BLOCKING.WAITTIME,
@.BLOCKING_LASTWAITTYPE = BLOCKING.LASTWAITTYPE,
@.BLOCKING_HOST =
CASE WHEN [CORPORATEDIRECTORY].[dbo].[ConcatenateName](SCD.LASTNAME,
SCD.FIRSTNAME, SCD.MIDDLENAME, SCD.PREFERREDNAME) IS NOT NULL
THEN rtrim(BLOCKING.hostname) + '-' +
[CORPORATEDIRECTORY].[dbo].[ConcatenateName](SCD.LASTNAME, SCD.FIRSTNAME,
SCD.MIDDLENAME, SCD.PREFERREDNAME)
ELSE rtrim(BLOCKING.hostname)
END
FROM SYSPROCESSES BLOCKING
LEFT OUTER JOIN PCDB.dbo.PC PCBLOCKING ON (BLOCKING.hostname =PCBLOCKING.MACHINEID)
LEFT OUTER JOIN PCDB.DBO.PERSON PERSONBLOCKING ON (PCBLOCKING.PERSONID =PERSONBLOCKING.PERSONID)
LEFT JOIN CORPORATEDIRECTORY.dbo.PERSON SCD ON (PERSONBLOCKING.CDID =SCD.PERSONID)
WHERE BLOCKING.SPID = @.BlockingSPID
IF @.BLOCKING_BLOCKEDBY <> 0
BEGIN
SET @.NESTNEXTLEVEL = @.NestLevel + 1
EXEC dbo.ShowBlockingSPID @.SampleTime, @.BLOCKING_BLOCKEDBY, @.NESTNEXTLEVEL
END
return 0
go
"Jim Heavey" <JimHeavey@.hotmail.com> wrote in message
news:O$u7BzDmDHA.2080@.TK2MSFTNGP10.phx.gbl...
> I was wanting to write a stored procedure which would identify queries
which
> are currently being blocked (spids 'blocked by' some other spid) when the
> stored procedure is being run.
> Is this possible? How do I go about figuring out how to do this?
>

Tuesday, February 14, 2012

BizTalk and SQL Server 2000

We're running BizTalk 2004 on top of SQL Server 2000. Due to the fact that BizTalk uses Distributed Transactions BizTalk requires a customized backup solution that uses the BEGIN TRANSACTION ... WITH MARK syntax. How does the WITH MARK work? We run a couple of very large transaction loads at various times during the week. These loads ran the BizTalkMsgBoxDb transaction log up to 18 Gig (the data file was only at 360 Meg). As the transaction log got bigger and bigger the server got slower and slower. Finally the custom backup job started erroring out on a memory error. Eventually the backup jobs stopped running due to an out of memory condition and then my users got locked out due to an out of memory condition. After I did some research (I rebooted the server which didn't help) I figured out that it was this WITH MARK that appeared to be having the issue. On a hunch I did a DBCC shrinkfile on the BizTalkMsgBoxDb transaction log and I got it down to 506 Meg. All of my problems cleared up. This is fine for the short term but these loads will not only continue they will increase in size and frequency since we are still in our testing phase, we haven't gotten to production yet. Is there a something I've overlooked here?Good info here:
http://msdn2.microsoft.com/en-us/library/ms187014.aspx|||Thank you for the article. What I really need is a very detailed explanation of how a transaction log mark works. Does the system try and open the transaction log like a text file (for example) in order to put a mark in? I've got a couple of databases in BizTalk that have transaction logs that grow rather large and once they get to the 1.5 Gig to 2 Gig size SQL Server starts to throw memory errors (SQL Server Standard Edition) when the TRANSACTION WITH MARK runs. I can get rid of the memory errors by running a backup then issuing a DBCC Shrinkfile but this isn't a viable option for my production system. Since this is BizTalk I was expecting that Microsoft would have a solution to my problem. Have you seen this before?|||

When a 'with mark' is set, the system will start keeping track of every operation between the database(s) involved in the dml session. This can get rather large if there are lots of changes.

So, unless you really need 'with mark' set, don't. Especially, if you are not creating a transaction across multiple databases.

|||Aaaa, but the 'with mark' is part of the custom backup solution that is supplied with BizTalk in order to handle the fact that BizTalk uses Distributed Queries all over the system. So my ultimate question is - how do I take a consistent backup of all of the BizTalk databases so that a restore would leave them in sync.? When I asked this question of some of the folks we had help us install and configure BizTalk they gave me the stored procedure that we run as our backup which uses the "with mark". Is there an alternative?