Showing posts with label allows. Show all posts
Showing posts with label allows. Show all posts

Wednesday, March 7, 2012

Context Connection Transaction

Hello Guys,

I need some some clarifications on how Context connections and transactions inter operate in CLR.

The context connection allows for ADO objects to be " running in the same transaction space". So the association to the current transaction is implied. So as long as I set for example my SqlCommand to use the context connection I am going to be running under the same transaction.

SqlConnection sqlConn = new SqlConnection("context connection=true");
SqlCommand sqlComm = new SqlCommand("EXEC myCommand", sqlConn);

I guess my ambiguity comes from the fact that the Transaction is not specifically specified.

In addition what happens upon a trigger that for example watches and insert on a table? If the insert occurs under a transaction, I would assume that I will be also picking up that transaction in the CRL Trigger, thus the whole operation would seem atomic.

Thank you,

Lubomir

Hi Lubomir!

I see that in your post you ask questions and give right answers to them yourself

Thank you,

Context connection and transactions

All -
Facts:
(a) SqlConnection allows only one "Context connection" to be opened at a tim
e.
(b) SqlConnection doesnt support parallel transactions. (calling a second
BeginTransaction before committing the first BeginTransaction throws
exception)
Problem:
Lets say a piece of C# code whose assembly is stored in SqlServer 2005 -
registered as SQLProcedure, is invoked.
Inside this code (which is now in SqlServer context) - i open a
SqlConnection as "context connection".
All the SqlCommand objects that uses this context connection, need the same
transaction (Lets say TransA) except one SqlCommand (LogCmd) that needs a
different transaction. (lets say TransB)
How to do this?
Calling BeginTransaction twice blows up.
Creating 2 seperate instances of SqlConnection with context connection =
true, also blows up.
Remember that somehow i might want to rollback TransA but always committ
TransB. For instance
try
{
// Do some actions
// SqlCommands that use TransA and TransB will be executed here
transA.Committ(); // things are fine - committ A
}
catch
{
transA.Rollback(); // things are incorrect - rollback A
}
finally
{
transB.Committ(); // Always comitt the logs...
}
How to do this when we are in context connection?
Regardz
Grafix."Grafix" <Grafix@.discussions.microsoft.com> wrote in message
news:54F45F4C-4F6B-44D7-8B13-0D55F13BB75C@.microsoft.com...
> All -
> Facts:
> (a) SqlConnection allows only one "Context connection" to be opened at a
> time.
> (b) SqlConnection doesnt support parallel transactions. (calling a second
> BeginTransaction before committing the first BeginTransaction throws
> exception)
> Problem:
> Lets say a piece of C# code whose assembly is stored in SqlServer 2005 -
> registered as SQLProcedure, is invoked.
> Inside this code (which is now in SqlServer context) - i open a
> SqlConnection as "context connection".
> All the SqlCommand objects that uses this context connection, need the
> same
> transaction (Lets say TransA) except one SqlCommand (LogCmd) that needs a
> different transaction. (lets say TransB)
> How to do this?
> Calling BeginTransaction twice blows up.
> Creating 2 seperate instances of SqlConnection with context connection =
> true, also blows up.
> Remember that somehow i might want to rollback TransA but always committ
> TransB. For instance
>
You will have exactly the same issue in TSQL. SQL Server does not support
autonomous transactions.
A common workaround is to write data into a table variable (or List<T> ), and
do something with it after the transaction is rolled back.
David|||I haven't gone into CLR stored procedures too much. But can't you add this
one SqlCommand (LogCmd) that needs a different transaction
into a seperate class and use the transaction option as requiresNew and with
the method haveing an autocommit tag to be true. and then call it from the
parent transaction.|||> one SqlCommand (LogCmd) that needs a different transaction
> into a seperate class and use the transaction option as requiresNew
There is the problem.
I am not able to have 2 active transaction scopes at the same time.
Remember LogCmd will be executed multiple times inbetween other regular
xxxCmd.
Which means i want 2 active transaction scopes (each with Option
"RequiresNew")
Unfortunately when i am in context connection (C# sp), i am not allowed to
create 2 connections that i can enlist with the TransactionScope.
I tried ur suggestion with the new .NET 2.0's
System.Transactions.TransactionScope class (Promotable transaction) for
seeing if i can enlist a single connection with multiple transactions - but
the problem is the same. So bad that they have introduced new Options like
TransactionScopeOption.Suppress and i am not able to use it still.
With one SqlConnection - u cannot associate with 2 different transaction
scopes.
And this C# sps allow only one connection at a time.
Seems i have to follow David Browne's suggestion of in-memory datastructure
to hold the logs and committ at the end.

Sunday, February 12, 2012

Constraint/identity which allows duplicate null fields

hi,

I've done Googling and forum hunting but haven't had success finding a simple answer... My table schema is such that it requires the (int) LinkedItemID field to be nullable but still those fields which are set must not be duplicates. I see constraint is out of question and also identity doesn't seem to fit since I'm not using autofill for this particular field. Is there some other way doing this on Sql Server 2005?

Thank you.

Make your value a foreign key constraint you can take the IDENTITY property of another table make sure your table is UNION compatible, create an index on another column in the same table and add that column in it through the new feature called INDEX Column include turn on the IGNORE_DUP_KEY option and you have a duplicate proof column. Now let me explain it UNION is a SET operator that performs implicit distinct by eliminating duplicates, and by adding it to an index it can also use the physical IGNORE_DUP_KEY which also eliminates duplicates and your column can get the benefits of an index without actually being the index. Run a search for UNION,IGNORE_DUP_KEY and INDEX COLUMN include in the BOL(books online). I am assuming you know you have to spend time with Management Studio to create this, post again if you still have question. Hope this helps.|||

Can't you just check before you do an INSERT?

IF NOT EXISTS( SELECT * FROM YourTable WHERE LinkedItemID = @.somevalue)

BEGIN

-- do the insert

END

|||

ndinakar:

Can't you just check before you do an INSERT?

IF NOT EXISTS( SELECT * FROM YourTable WHERE LinkedItemID = @.somevalue)

BEGIN

-- do the insert

END

That will do what IGNORE_DUP_KEY will do but a UNION will also eliminate duplicates in a Query of more than one table, the main difference between UNION and UNION ALL. It is the reason UNION comes with more restriction than UNION ALL.

|||

I am confused why we need a UNION, foreign key constraint, INDEX COLUMN etc in this scenario. IGNORE_DUP_KEY will work if the index has already been created with that option.

|||

(My table schema is such that it requires the (int) LinkedItemID field to be nullable but still those fields which are set must not be duplicates. I see constraint is out of question )

This was the original poster's need I just showed all can be achived with a combination of SET algebra and the physical. UNION will eliminate duplicates in a query with another column that will introduce duplicates in the result and it comes with compatibility requirement in the table definition, you are checking for duplicates only during insert. Index column include will let that column to be included in a Unique index which require NOT NULL by default, so use the IGNORE_DUP_KEY option and SQL Server just toss the duplicates and continue any insert because ADO.NET does more than one insert. One more thing foriegn key constraints are nullable by ANSI SQL definition.

http://msdn2.microsoft.com/en-us/library/ms190806.aspx

|||

hi,

thanks all of you for your assistance. I still think your solution is far too complicated - there must be some easier way? Why I don't do a check before INSERT - it's because there are about 10 stored procs in my database which work with this particular field and it would be so much easier to do this by some kind of constraint (or even trigger?!)...

|||

EDIT

The quick solution is Unique Constraint because it allows NULLs and the other easy option is through the index column include in a Unique index, you just include it and use the IGNORE_DUP_KEY option, it is not complicated. UNION is complicated to set up if it was not included during the database design. Hope this helps.

http://msdn2.microsoft.com/en-us/library/ms191166.aspx