Greenplum - How To Handle Deadlock - sql-server

When try to run SQL transaction from Greenplum. getting this error.
Transaction (Process ID 52) was deadlocked on lock resources with
another process and has been chosen as the deadlock victim.
Rerun the transaction.
We Tried :
On SQL server it is working But we wanted to write same transaction on greenplum
Transaction A
RETRY: -- Label RETRY
BEGIN TRANSACTION
BEGIN TRY
truncate table tablename
WAITFOR DELAY '00:00:05' -- Wait for 5 ms
Insert into tablename
COMMIT TRANSACTION
END TRY
BEGIN CATCH
PRINT 'Rollback Transaction'
ROLLBACK TRANSACTION
IF ERROR_NUMBER() = 1205 -- Deadlock Error Number
BEGIN
WAITFOR DELAY '00:00:00.05' -- Wait for 5 ms
GOTO RETRY -- Go to Label RETRY
END
END CATCH
OUTPUT :
IT INCLUDES
Conversion of mentioned sql transaction (retry and try/catch )block in greenplum syntax.
As process ID keep changing , want to avoid hardcode value when passing into transaction.
3.Also, I am trying to understand this error belongs to SQL SERVER OR transaction we written in greenplum.
Data flow in talend is:
**Read from MS SQL SERVER >> write into hdfs >> load into greenplum**
Any help on it would be much appreciated ?

You cannot begin or end the transaction within a transaction in Greenplum. It auto commit or auto roll back.
Multi-Version Concurrency Control, there is always a data consistency and also query always executes in sequential within parallel mechanisms.
RETRY: -- Label RETRY
BEGIN
truncate table tablename
select pg_sleep(5) -- Wait for 5 ms
Insert into tablename
RAISE INFO 'Rollback Transaction'
IF ERROR_NUMBER = 1205 -- Deadlock Error Number
THEN
select pg_sleep(5) -- Wait for 5 ms
-- Go to Label RETRY
END

Related

Difference between batch and transaction in SQL Server in terms of handling errors

I am having a bit of hard time understanding how errors affect the completion of batches and/or transactions.
For instance:
BEGIN TRAN;
SELECT 1/0 AS Error;
ROLLBACK;
BEGIN TRAN;
SELECT 1/1 AS NOError;
COMMIT;
GO
Should not the second transaction succeed even though the first fails? Are not transactions dealt with on one-by-one basis? And what is the role played by batches here?
I was reading about SET XACT_ABORT ON command, and the MSDN says:
When SET XACT_ABORT is ON, if a Transact-SQL statement raises a run-time error, the entire transaction is terminated and rolled back.
If it only fails the containing transaction, why the second transaction is never reached?

commit and rollback conflict

I faced one problem in this query execution on Microsoft SQL Server Management Studio
CREATE DATABASE myDB
USE myDB
CREATE TABLE udata(uid INT PRIMARY KEY identity(101, 2),
uname VARCHAR(25), unum INT UNIQUE)
CREATE TABLE usalary(sid INT PRIMARY KEY identity(1, 1),
salary NUMERIC(18, 0), FKuid INT REFERENCES udata(uid))
INSERT INTO udata VALUES ('yogesh', 99)
INSERT INTO udata VALUES ('tejas', 88)
INSERT INTO usalary VALUES (15000, 103)
BEGIN TRANSACTION
SAVE TRANSACTION SP1
DELETE FROM udata WHERE uid = 1
COMMIT;
ROLLBACK to SP1
SELECT * FROM udata WHERE uid=1
BEGIN TRANSACTION
SAVE TRANSACTION SP2
TRUNCATE TABLE usalary
COMMIT
ROLLBACK to SP2
SELECT * FROM usalary
here when we commit the transaction it should be saved in database but after rollback the data will come back.How's that possible??
Here my question is simple.
in SQL documentation it is mentioned that after commiting any query or transaction we can not rollback.(we can not get our previous state of database.)
like if we create savepoint a and perform delete query on our database and explicitly give commit.
the documentation say that we can't rollback from this state but if i execute rollback command here I get my data back.
The whole series of command(query) is mentioned here for ease who wants to help from create database command to rollback command.
For a query like this:
BEGIN TRANSACTION
SAVE TRAN t1
DELETE FROM udata;
COMMIT;
ROLLBACK TRANSACTION t1
You will get an error: The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.. Sure, no rollback after a commit.
But if you try to wrap it in another transaction:
BEGIN TRANSACTION
BEGIN TRANSACTION
SAVE TRAN t1
DELETE FROM udata;
COMMIT;
ROLLBACK TRANSACTION t1
COMMIT
This will work fine. Why? documentation on Nesting Transactions says:
Committing inner transactions is ignored by the SQL Server Database Engine. The transaction is either committed or rolled back based on the action taken at the end of the outermost transaction.
My guess here is: either your not posting whole query here and there is a BEGIN TRANSACTION statement somewhere else or you have been testing transactions inside Management Studio and somewhere along the way you executed BEGIN TRANSACTION without matching ROLLBACK or COMMIT. In the later case, try to execute single ROLLBACK statement until you get an error. You can also just restart Management Studio.

BEGIN TRY/CATCH and MSDTC error

1/ The following code snippet show me the expected error: The INSERT statement conflicted with the FOREIGN KEY constraint FK_...
SET XACT_ABORT ON;
BEGIN TRANSACTION
INSERT INTO linkedsrv1.db1.[dbo].tbl1 ([Col1], [Col2])
VALUES (1200, 0)
COMMIT TRANSACTION
2/ But when I put this in a BEGIN TRY/CATCH, the error message is vague: Msg 1206, Level 18, State 118, Line 18
The Microsoft Distributed Transaction Coordinator (MS DTC) has cancelled the distributed transaction.
SET XACT_ABORT ON;
BEGIN TRY
BEGIN TRANSACTION
-- Error is on this line
INSERT INTO linkedsrv1.db1.[dbo].tbl1 ([IdWebsite], [IdProductType])
VALUES (1200, 0)
COMMIT TRANSACTION
END TRY
BEGIN CATCH
PRINT 'Error' -- Code not reached
SELECT ERROR_NUMBER(), ERROR_MESSAGE(), ERROR_SEVERITY(), ERROR_STATE()
IF XACT_STATE() != 0
ROLLBACK TRANSACTION
END CATCH
Any idea why this happens?
Later edit:
It works in case I remove the unneeded explicit transaction. It is still not clear why I get this error when I put BEGIN/COMMIT TRAN.
I get the same error in case I have multiple inserts in multiple tables situated on linked server.
Any comment / remark is welcomed.
From MSDN:
SYMPTOMS
Consider the following scenario. You use the SQL Native Client OLE DB provider (SQLNCLI) in SQL Server 2005 to create a linked server. You create a distributed transaction. The distributed transaction contains a query that uses the linked server to retrieve data from a table. When you commit the distributed transaction, you may receive the following error message:
Msg 1206, Level 18, State 167, Line 3
The Microsoft Distributed Transaction Coordinator (MS DTC) has cancelled
the distributed transaction.
Additionally, you may receive the following error message when you run a query after this behavior occurs:
Msg 8525, Level 16, State 1, Line 1
Distributed transaction completed. Either enlist this session in a new
transaction or the NULL transaction.
This problem occurs if the following conditions are true:
You use the SQLNCLI provider to create a linked server between two
instances of SQL Server 2005.
The XACT_ABORT option is set to ON.
In the distributed transaction, you try to release a rowset before
all rows in the rowset are processed.
Note This problem may also occur if you call the ReleaseRows method in a distributed transaction to release a rowset before you commit a distributed transaction in an application.
CAUSE
This problem occurs because the SQLNCLI provider incorrectly sends an attention signal to the linked server to roll back the distributed transaction.
WORKAROUND
To prevent the SQLNCLI provider from sending an attention signal to the server, use the SQLNCLI provider to consume fully any rowsets that the OLE DB consumer creates.
Update
you need to configure 'remote proc trans' to "1" in server parameters.
Ex:
exec sp_configure 'remote proc trans','1'
reconfigure with override
This will permmit you to execute any distributed queries.
More Update
If you are using .Net framework in front end too, then I think you can use
TransactionScope Class. Remove transaction from query and put the Transaction in code level.
I have went to through this pain!
If you are performing any CRUD operation on a single table TRANSACTION is not needed.
In this case, the problem is, XACT_STATE() returns -1 because there is an error in the active transaction. But, ROLLBACK TRANSACTION fails, since there is NO transactions happened. You did only one transaction, INSERT, which failed, so there are no other transactions to rollback.
Its always better to relay on ##TRANCOUNT than XACT_STATE() (at least in this case).
to make it work, change like this(though I don't support TRAN for single table):
IF ##TRANCOUNT > 0
ROLLBACK TRANSACTION
BEGIN TRANSACTION starts a distributed transaction between the server running the statements and the linked server, since potentially you can run updates against both servers. When the INSERT fails it needs to cancel the distributed transaction, thus the error you are getting. So you have to handle errors on two levels (insert and transaction). In this scenario, you'll need two TRY/CATCH blocks as follows:
SET XACT_ABORT ON;
BEGIN TRY
BEGIN TRANSACTION
BEGIN TRY
-- Error is on this line
INSERT INTO linkedsrv1.db1.[dbo].tbl1 ([IdWebsite], [IdProductType])
VALUES (1200, 0)
END TRY
BEGIN CATCH
SELECT 'Insert Error', ERROR_NUMBER(), ERROR_MESSAGE(), ERROR_SEVERITY(), ERROR_STATE()
RAISERROR (15600,-1,-1, 'INSERT ERROR');
END CATCH
COMMIT TRANSACTION
END TRY
BEGIN CATCH
SELECT 'Transaction Error', ERROR_NUMBER(), ERROR_MESSAGE(), ERROR_SEVERITY(), ERROR_STATE()
IF XACT_STATE() != 0
ROLLBACK TRANSACTION
END CATCH

begin transaction and commit transaction in MS SQL [duplicate]

This question already has answers here:
What happens if you don't commit a transaction to a database (say, SQL Server)?
(10 answers)
Closed 9 years ago.
If I Enclose a query between Begin Transaction and commit transaction in MS SQL, what will happen if i abort or stop the execution of the query. Will all the changes that had been done during executing ROLLBACKED.?
Your transaction can remain open until you call something like ROLLBACK TRANSACTION or COMMIT TRANSACTION, or until SQL takes some action on it.
More info:
SQL Server and connection loss in the middle of a transaction
What happens to an uncommitted transaction when the connection is closed?
What happens if you don't commit transaction in a database (say SQL Server)
I actually like to take advantage of this when testing large updates or corrections. You can have something like this:
-- BEGIN TRANSACTION
-- ROLLBACK TRANSACTION
-- COMMIT TRANSACTION
/*
A bunch of SQL code here
*/
Then you can highlight/run the BEGIN TRANSACTION, then run the whole script. If you're happy with the results, you can highlight/run the COMMIT TRANSACTION. If not, run the ROLLBACK TRANSACTION. Since those lines are commented out, they don't affect your overall transaction unless you explicitly highlight and run them.
It depends on your code. As long as your transaction exist, all changes will be pending a rollback or a commit.
You might want to look at this.
No. Transaction will still be active - you didn't rollback after all, did you? :)
Run this example and see what happens. If you break during transaction, you'll see value 2 is in a table, but you have to rollback or commit.
select 1 as x into #xxx
GO
begin transaction
insert into #xxx(x) select 2
-- ctrl+break before time runs out.
waitfor delay '00:00:10'
commit transaction
-- now try this:
select * from #xxx
rollback transaction
select * from #xxx

In SQL Server 2005 emulating autonomous transaction

I have needs to keep some of log data in different tables even my transaction is rolled back.
I already learned that in SQL Server it is impossible do something like this
begin tran t1
insert ...
insert ...
select ...
begin tran t2
insert into log
commit tran t2
rollback tran t1
select * from log -- IS EMPTY ALWAYS
So I try hacking SQL Server that I madded CLR which is going to export data need for LOG to local server disk in XML format. CLR Code is simple as it can be:
File.WriteAllText(fileName, xmlLog.Value.ToString());
Before I release this in production bases Ill love to hear your toughs about this technique.
Here are few questions:
Is there other better way to accomplish autonomous transaction in SQL Server 2005
How can be bad holding my transaction uncommitted while SQL Server is executing CLR (amount of data written by SQL is relative small about 50 - 60 records of 3 integers and 4 floats)
I would suggest using a Table Variable as it is not affected by the Transaction (this is one of the methods listed in the blog noted by Martin below the question). Consider doing this, which will work in SQL Server 2005:
DECLARE #TempLog TABLE (FieldList...)
BEGIN TRY
BEGIN TRAN
INSERT...
INSERT INTO #TempLog (FieldList...) VALUES (#Variables or StaticValues...)
INSERT...
INSERT INTO #TempLog (FieldList...) VALUES (#Variables or StaticValues...)
COMMIT TRAN
END TRY
BEGIN CATCH
IF (##TRANCOUNT > 0)
BEGIN
ROLLBACK TRAN
END
/* Maybe add a Log message to note that we ran into an error */
INSERT INTO #TempLog (FieldList...) VALUES (#Variables or StaticValues...)
END CATCH
INSERT INTO RealLogTable (FieldList...)
SELECT FieldsList
FROM #TempLog
Please note that while we are making use of the fact that Table Variables are not part of the transaction, that does create a potential situation where this code does a COMMIT but errors (or server crashes) before the INSERT INTO RealLogTable and you will have lost the logging for the data that did make it in. At this point there would be a disconnect as there is data but no record of it being inserted as far as RealLogTable is concerned. But this is just the obvious trade-off for being able to bypass the Transaction.

Resources