TransactionScope how can I tell if a Connection has been enlisted - transactionscope

I have a method that has a connection as one of it's parameters:
e.g. public void Foo(SqlConnection pConn) { }
within Foo is it possible to determine if pConn is enlisted in any transactionscope?

If its sql server issue a select ##trancount would be one way

Related

Passing a stream or a String to Flyway API instead of locations

I was wondering if there is a way for Flyway to accept an actual SQL migration as a string or a stream instead of searching for it on a classpath?
I'm constructing the SQL migration in Java on the fly and would like to call Flyway API and pass the migration as a paramter.
Please, let me know if this is possible.
Thank you
Not entirely what you are asking for, but looks like Java-based migrations might be a solution.
Basically instead of V1_0__script.sql you write V1_0__script.java class implementing JdbcMigration. Inside that class you have access to JDBC Connection:
class V1_0__script implements JdbcMigration {
public void migrate(Connection connection) throws Exception {
//...
}
}
In migrate() you are free to run your custom SQL queries.
There is no API available for this.
However, if you construct your SQL on the fly, it surely must be possible to construct it one statement at a time. Each statement can then be executed using the Connection parameter you get in a JdbcMigration

The transaction manager has disabled its support for remote/network transactions

I'm using SQL Server and ASP.NET. I have the following function:
Using js = daoFactory.CreateJoinScope()
Using tran = New Transactions.TransactionScope()
'...
tran.Complete()
End Using
End Using
However, the following exception is thrown:
The transaction manager has disabled its support for remote/network transactions.
Description of JoinScope:
Public Class JoinScope
Implements IJoinScope
Implements IDisposable
'...
End Class
I have worked this way in another application with the same environment without a problem, but here I have this problem. What could I do to fix the issue?
Make sure that the "Distributed Transaction Coordinator" Service is
running on both database and client.
Also make sure you check "Network DTC Access", "Allow Remote Client",
"Allow Inbound/Outbound" and "Enable TIP".
To enable Network DTC Access for MS DTC transactions
Open the Component Services snap-in.
To open Component Services, click Start. In the search box, type dcomcnfg, and then press ENTER.
Expand the console tree to locate the DTC (for example, Local DTC) for which you want to enable Network MS DTC Access.
On the Action menu, click Properties.
Click the Security tab and make the following changes:
In Security Settings, select the Network DTC Access check box.
In Transaction Manager Communication, select the Allow Inbound and Allow Outbound check boxes.
I had a store procedure that call another store Procedure in "linked server".when I execute it in ssms it was ok,but when I call it in application(By Entity Framework),I got this error.
This article helped me and I used this script:
EXEC sp_serveroption #server = 'LinkedServer IP or Name',#optname = 'remote proc transaction promotion', #optvalue = 'false' ;
for more detail look at this:
Linked server : The partner transaction manager has disabled its support for remote/network transactions
In my scenario, the exception was being thrown because I was trying to create a new connection instance within a TransactionScope on an already existing connection:
Example:
void someFunction()
{
using (var db = new DBContext(GetConnectionString()))
{
using (var transaction = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted }))
{
someOtherFunction(); // This function opens a new connection within this transaction, causing the exception.
}
}
}
void someOtherFunction()
{
using (var db = new DBContext(GetConnectionString()))
{
db.Whatever // <- Exception.
}
}
I was getting this issue intermittently, I had followed the instructions here and very similar ones elsewhere. All was configured correctly.
This page: http://sysadminwebsite.wordpress.com/2012/05/29/9/ helped me find the problem.
Basically I had duplicate CID's for the MSDTC across both servers. HKEY_CLASSES_ROOT\CID
See: http://msdn.microsoft.com/en-us/library/aa561924.aspx section Ensure that MSDTC is assigned a unique CID value
I am working with virtual servers and our server team likes to use the same image for every server. It's a simple fix and we didn't need a restart. But the DTC service did need setting to Automatic startup and did need to be started after the re-install.
Comment from answer: "make sure you use the same open connection for all the database calls inside the transaction. – Magnus"
Our users are stored in a separate db from the data I was working with in the transactions. Opening the db connection to get the user was causing this error for me. Moving the other db connection and user lookup outside of the transaction scope fixed the error.
I post the below solution here because after some searching this is where I landed, so other may too. I was trying to use EF 6 to call a stored procedure, but had a similar error because the stored procedure had a linked server being utilized.
The operation could not be performed because OLE DB provider _ for linked server _ was unable to begin a distributed transaction
The partner transaction manager has disabled its support for remote/network transactions*
Jumping over to SQL Client did fix my issue, which also confirmed for me that it was an EF thing.
EF model generated method based attempt:
db.SomeStoredProcedure();
ExecuteSqlCommand based attempt:
db.Database.ExecuteSqlCommand("exec [SomeDB].[dbo].[SomeStoredProcedure]");
With:
var connectionString = db.Database.Connection.ConnectionString;
var connection = new System.Data.SqlClient.SqlConnection(connectionString);
var cmd = connection.CreateCommand();
cmd.CommandText = "exec [SomeDB].[dbo].[SomeStoredProcedure]";
connection.Open();
var result = cmd.ExecuteNonQuery();
That code can be shortened, but I think that version is slightly more convenient for debugging and stepping through.
I don't believe that Sql Client is necessarily a preferred choice, but I felt this was at least worth sharing if anyone else having similar problems gets landed here by google.
The above Code is C#, but the concept of trying to switch over to Sql Client still applies. At the very least it will be diagnostic to attempt to do so.
I was having this issue with a linked server in SSMS while trying to create a stored procedure.
On the linked server, I changed the server option "Enable Promotion on Distributed Transaction" to False.
Screenshot of Server Options
If you could not find Local DTC in the component services try to run this PowerShell script first:
$DTCSettings = #(
"NetworkDtcAccess", # Network DTC Access
"NetworkDtcAccessClients", # Allow Remote Clients ( Client and Administration)
"NetworkDtcAccessAdmin", # Allow Remote Administration ( Client and Administration)
"NetworkDtcAccessTransactions", # (Transaction Manager Communication )
"NetworkDtcAccessInbound", # Allow Inbound (Transaction Manager Communication )
"NetworkDtcAccessOutbound" , # Allow Outbound (Transaction Manager Communication )
"XaTransactions", # Enable XA Transactions
"LuTransactions" # Enable SNA LU 6.2 Transactions
)
foreach($setting in $DTCSettings)
{
Set-ItemProperty -Path HKLM:\Software\Microsoft\MSDTC\Security -Name $setting -Value 1
}
Restart-Service msdtc
And it appears!
Source: The partner transaction manager has disabled its support for remote/network transactions
In case others have the same issue:
I had a similar error happening. turned out I was wrapping several SQL statements in a transactions, where one of them executed on a linked server (Merge statement in an EXEC(...) AT Server statement). I resolved the issue by opening a separate connection to the linked server, encapsulating that statement in a try...catch then abort the transaction on the original connection in case the catch is tripped.
I had the same error message. For me changing pooling=False to ;pooling=true;Max Pool Size=200 in the connection string fixed the problem.

How to write unit case for remote database connection in asp web application

I am new to unit testing for web applications
I have a function which creates a connection to a remote mysql database and perform some operations on it .
I want to have a test case which tests the connection is closed or not after the operations on database.
for example
fun1()
{
ODBCConnection con = new ODBCConnection(connString);
con.open();
}
in the above function, the connection is not closed?
how do i check this? can any one help?
In .Net, it's generally best to open your connections immediately before you use them. So rather than building (and testing) a function that connects to the database, you build and test a function that returns the correct connectionstring. You also have a reference database for your testing environment, and so you build your data access methods and create their own connection and test them against your reference database, that the right results come back.
Okay, based on your comment I can help you. Since you will be opening and closing the connection in the same function (as you should), you can do this:
public void fun1()
{
using (ODBCConnection con = new ODBCConnection(connString))
{
con.open();
//use the connection here
}
//connection is closed here because of the using block, even if an exception is thrown
}
There is no need to check if the connection closes in the code above. It will be closed in a timely manner by the using block, and that's guaranteed as much as anything can be in software. Just make sure you use that pattern everywhere you use connections.
In unit testing, the "units" to be tested are methods/functions. You test that the function performs as you expect it to, and nothing more. If you want to test specifically if a connection is closed, than the way to do it is to write a function to close the connection, and test that.

asp.net webservice OnUnload?

I'm creating a web service which has a number of methods, all of which make use of a SqlConnection. It seems logical that I would declare a class level connection and initialise it in the web service constructor.
Problem is I cannot find a definitive way to release the connection when the web service call completes, so I have a connection leak. I've tried overriding the Dipose() method but it doesn't get called in a reasonable timeframe (actually not at all in my testing). For good measure I also tried attaching a handler to the Disposed() event but as expected same problem.
Is there nothing similar to Page.OnUnload for web service classes? It seems hard to believe I would have to establish a separate connection in every individual method.
Any suggestions?
It seems logical that I would declare a class level connection and initialise it in the web service constructor.
No, this doesn't seem logical at all. ADO.NET uses a connection pooling so that you don't need to do this. This connection pool is per connection string per application domain.
So you could simply draw a new connection from the pool in each web method and return it to the pool at the end (the using statements will take care of this):
[WebMethod]
public void Foo()
{
// Here you are NOT creating a new connection to the database
// you are just drawing one from the connection pool
using (var conn = new SqlConnection(SomeConnectionString))
using (var cmd = conn.CreateCommand())
{
// Here you are NOT opening a new connection to the database
conn.Open();
cmd.CommandText = "SELECT id FROM foo";
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
// do something with the results
}
}
} // Here you are NOT closing the connection, you are just returning it to the pool
}
So here's an advice: don't try to manage connections manually by using some class fields, static fields, ... Leave this management to ADO.NET as it does it better.
Remark: The code I've shown usually resides in a data access layer which is called by the web method.

Is using a singleton for the connection a good idea in ASP.NET website

I'm currently using a singleton on my web application so that there is always only one connection to the database.
I want to know if it's a good idea because right now I'm having trouble with that error:
Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
Another important point is that my website is currently in dev and not a lot of people go on it so I don't understand why I get this error!
Here is the code of my singleton:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
/// <summary>
/// This class take care of all the interaction with the database
/// </summary>
public class DatabaseFacade
{
SqlConnection m_conn = null;
string m_csLanguageColumn;
//Variables that implement the Singleton pattern
//Singleton pattern create only one instance of the class
static DatabaseFacade instance = null;
static readonly object padlock = new object();
/// <summary>
/// Private constructor. We must use Instance to use this class
/// </summary>
private DatabaseFacade()
{
}
/// <summary>
/// Static method to implement the Singleton
/// </summary>
public static DatabaseFacade Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new DatabaseFacade();
}
return instance;
}
}
}
/// <summary>
/// Do the connection to the database
/// </summary>
public void InitConnection(int nLanguage)
{
m_conn = new SqlConnection(GetGoodConnectionString());
try
{
//We check if the connection is not already open
if (m_conn.State != ConnectionState.Open)
{
m_conn.Open();
}
m_csLanguageColumn = Tools.GetTranslationColumn(nLanguage);
}
catch (Exception err)
{
throw err;
}
}
}
Thanks for your help!
Using a single connection is an extremely bad idea - if access to the connection is properly locked, it means that ASP.NET can only serve one user at a time, which will seriously limit your application's ability to grow.
If the connection is not properly locked, things can get really weird. For example, one thread might dispose the connection while another thread is trying to execute a command against it.
Instead of using a single connection, you should just create new connection objects when you need them, to take advantage of connection pooling.
Connection pooling is the default behavior for the SqlClient classes (and probably other data providers). When you use connection pooling, any time you 'create' a connection, the connection will actually be pulled from a pool of existing ones so that you don't incur the costs of building one from scratch each time. When you release it (close it or dispose of it) you return it to the connection pool, keeping your total count of connections relatively low.
Edit: You'll see the error you mention (The timeout period elapsed prior to obtaining a connection from the pool) if you're not closing (or disposing) your connections. Make sure you do that as soon as you're done using each connection.
There are several good stack overflow questions that discuss this, which I suspect might be helpful!
Why isn’t SqlConnection
disposed/closed?
What is the proper way to ensure a
SQL connection is closed when an
exception is thrown?
No, it's a bad idea. You use connection pooling.
The reason why using a Connection to the database as a singleton is an horrific idea, is because every 2nd+ connection will then have to WAIT for the first connection to be released.
A singleton means that there's only one database connection object, to connect to the db. So if a second person wants to connect to it, they need to wait until they can access that object.
That's bad news.
Just keep creating new instances of the database connection object, when required. The trick here is to open the connection as late as possible and then close that connection as soon as possible.
The most expensive operation in a database connection object, is the actual connection. not the creation.
No need for a Singleton. Here are some articles on connection pooling:
.NET 1.1
Connection Pooling for the .NET Framework Data Provider for SQL Server
.NET 2.0
Using Connection Pooling with SQL Server
.NET 3.0
Using Connection Pooling
.NET 3.5
SQL Server Connection Pooling (ADO.NET)
.NET 4.0
SQL Server Connection Pooling (ADO.NET)

Resources