I am fighting with stored procedure with referenced linkedserver. Linked server is accesible over internet via port forwarding - so no VPN, LAN.
Servers are on both sides MS SQL SERVER 2008 EE v. 10.0.5512
Configurations Linked server, DTC:
cannot insert images yet:(
enable promotion of distributed transaction = false
RPC = false
RPC out = false
Network DTC Access checked
Allow inbound true
Allow outbound true
No authentication Required
Stored procedure looks like
CREATE PROCEDURE [dbo].[spSynchronizeArticles]
-- Add the parameters for the stored procedure here
(
#pDebug bit,
#siteId bigint
)
AS
BEGIN
SELECT *
FROM [LinkedServer].[MyDatabase].dbo.Storages
WHERE Storage.siteId = #siteId
RETURN 0
END
As you can see no transaction here. If I am correct the MS DTC is creating transaction every time when the linked server is called.
I am calling this procedure from c# like this
SqlCommand sqlCmd = new SqlCommand("spSynchronizeArticles");
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.Parameters.AddWithValue("#pDebug", false);
sqlCmd.Parameters.AddWithValue("#siteId", siteId);
SqlParameter returnValue = new SqlParameter("returnVal", SqlDbType.Int);
returnValue.Direction = ParameterDirection.ReturnValue;
sqlCmd.Parameters.Add(returnValue);
using (SqlConnection conn = new SqlConnection(Context.LocalData.ConnectionString))
{
try
{
try
{
conn.Open();
sqlCmd.Connection = conn;
sqlCmd.ExecuteScalar();
return Convert.ToInt32(returnValue.Value);
}
catch (Exception ex)
{
//log exception to file
return -1;
}
}
finally
{
conn.Close();
}
}
}
This c# code is called in infinite while to synchronize data. In same Thread and while there is also another method called which is getting data from file (if any exist) and saving them to local DB.
The SynchronizeArticles method is invoking more often and everything is working, but once the method for getting data from file is called, the SynchronizeArticles always throw this exception
System.Data.SqlClient.SqlException (0x80131904): MSDTC on server
'LocalServer\SQLEXPRESS2008' is unavailable.
The method is using Transaction and looks like
public void FillDataFromViewWithTrans(DataTable dt, string wherePhrase)
{
dt.Rows.Clear();
SqlCommand sql = new SqlCommand(String.Format(#"SELECT *
FROM SomeView
{0}", String.IsNullOrEmpty(wherePhrase) ? String.Empty : "WHERE " + wherePhrase));
using (SqlConnection conn = new SqlConnection(Context.LocalData.ConnectionString))
{
SqlTransaction trans = null;
try
{
try
{
conn.Open();
trans = conn.BeginTransaction(IsolationLevel.RepeatableRead);
sql.Transaction = trans;
sql.Connection = conn;
SqlDataAdapter dA = new SqlDataAdapter(sql);
dA.Fill(dt);
trans.Commit();
}
catch (Exception ex)
{
trans.Rollback();
//log exception to file
return;
}
}
finally
{
conn.Close();
}
}
}
This is just illustration samples :)
Tell me what I am missing.
Additionally I have big troubles with the MS DTC with various errors
From C# code when some users calls the procedure manually they sometimes got exception:
The operation could not be performed because the OLE DB provider
'SQLOLEDB' was unable to begin a distributed transaction.
When I put the begin distributed transaction inside the stored procedure I got:
Warning: Fatal error 8510 occurred at Apr 10 2013 9:07AM. Note the
error and time, and contact your system administrator.
What only helps is the restart of the windows service or the UI application. From the MS SQL management studio the procedure works all the time without problems.
Now I must say I am desperate, what am I missing?
Edit:
int i = 0;
while (true)
{
i++;
if ((i % 9) == 0)
{
//local select with transaction Works all the time
CallLocalSelectWithTransaction();
}
// CallProcedure works 8 times, after first calling of CallLocalSelectWithTransaction
// the callProcedure works no more.
CallProcedure(); // procedure with linked server
}
Related
I am trying to print crystal report in PDF format , and on my local machine it’s working fine. But when I publish application to the server, it’s giving me the following error on Print button.
Exception Details: System.Runtime.InteropServices.COMException: Database logon failed.
Below is my code in my controller
public ActionResult Export(int Id)
{
ReportDocument rd = new ReportDocument();
rd.Load(Path.Combine(Server.MapPath("~/Reports/GcReport.rpt")));
var query = rLAService.GetGeneralConsignmentById(Id);
var querylist = new List<GeneralConsignmentDto> { query };
rd.SetDataSource(querylist);
rd.SetParameterValue("Id", Id);
//rd.SetDataSource(rLAService.GetGeneralConsignmentById(Id));
Response.Buffer = false;
Response.ClearContent();
Response.ClearHeaders();
Stream stream = rd.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
stream.Seek(0, SeekOrigin.Begin);
return File(stream, "application/pdf", "GC Report.pdf");
}
Edit
Ok, after digging throuh the problem, i found that error is table name generalconsignment1 does not found. But problem is it is taking automatically instead of generalconsignment.now how to handle this situation?
I'm trying to use dapper with mysql in .net core 1.0. I'm using this mysql connector: https://github.com/bgrainger/MySqlConnector
I know the connector is in alpha but I was wondering if anyone had a similar issue when using it together with dapper.
This is my simple model:
public List<GeneralModel> GetAllLists()
{
try
{
using (DbConnection connection = new MySqlConnection("Server=localhost;Database=lists;Uid=Unnamed;Pwd=lol;"))
{
return connection.Query<GeneralModel>("SELECT * FROM lists.general").ToList();
}
}
catch (Exception)
{
throw;
}
}
And this is the controller:
public IActionResult Index()
{
GeneralModel GenRepo = new GeneralModel();
return View(GenRepo.GetAllLists());
}
When I go to the index page for the first time, it works. If I refresh, I get an "Access denied for user...". I have no idea what could be causing the error. I don't think the problem is in my code.
Edit:
I guess the problem is in the connector, since this also returns the error after a refresh:
List<GeneralModel> lists = new List<GeneralModel>();
using (DbConnection connection = new MySqlConnection("Server=localhost;Database=lists;Uid=Unnamed;Pwd=lol;"))
{
using (DbCommand myCommand = connection.CreateCommand())
{
myCommand.CommandText = "SELECT * FROM lists.general";
connection.Open();
using (DbDataReader myReader = myCommand.ExecuteReader())
{
while (myReader.Read())
{
GeneralModel tmpGen = new GeneralModel();
tmpGen.name = myReader["name"].ToString();
tmpGen.description = myReader["description"].ToString();
tmpGen.language = myReader["language "].ToString();
lists.Add(tmpGen);
}
}
connection.Close();
}
}
return lists;
This bug was caused by MySqlConnector not correctly handling the fast path for a COM_CHANGE_USER packet.
MySQL Server (versions 5.6 and 5.7) doesn't appear to immediately accept the user's credentials, but always returns an Authentication Method Switch Request Packet. MariaDB (which you are using) does implement the fast path and immediately returns an OK packet.
The connector has now been updated to handle this response and should stop throwing the spurious "Access Denied" exceptions. The fix is in 0.1.0-alpha09.
I am trying to create a Merge Replication using RMO Programming which i got from here!
string publisherName = "DataSourceName";
string publicationName = "AdvWorksSalesOrdersMerge";
string publicationDbName = "AdventureWorksDW2008R2";
ReplicationDatabase publicationDb;
MergePublication publication;
// Create a connection to the Publisher.
ServerConnection conn = new ServerConnection(publisherName);
try
{
//Connect to the Publisher.
conn.Connect();
// Enable the database for merge publication.
publicationDb = new ReplicationDatabase(publicationDbName, conn);
if (publicationDb.LoadProperties())
{
if (!publicationDb.EnabledMergePublishing)
{
publicationDb.EnabledMergePublishing = true;
}
}
else
{
// Do something here if the database does not exist.
throw new ApplicationException(String.Format(
"The {0} database does not exist on {1}.",
publicationDb, publisherName));
}
// Set the required properties for the merge publication.
publication = new MergePublication();
publication.ConnectionContext = conn;
publication.Name = publicationName;
publication.DatabaseName = publicationDbName;
// Enable precomputed partitions.
publication.PartitionGroupsOption = PartitionGroupsOption.True;
//Specify the Windows account under which the Snapshot Agent job runs.
// This account will be used for the local connection to the
// Distributor and all agent connections that use Windows Authentication.
publication.SnapshotGenerationAgentProcessSecurity.Login = userid;
publication.SnapshotGenerationAgentProcessSecurity.Password = password;
//Explicitly set the security mode for the Publisher connection
// Windows Authentication (the default).
publication.SnapshotGenerationAgentPublisherSecurity.WindowsAuthentication = true;
//Enable Subscribers to request snapshot generation and filtering.
publication.Attributes |= PublicationAttributes.AllowSubscriberInitiatedSnapshot;
publication.Attributes |= PublicationAttributes.DynamicFilters;
// Enable pull and push subscriptions.
publication.Attributes |= PublicationAttributes.AllowPull;
publication.Attributes |= PublicationAttributes.AllowPush;
if (!publication.IsExistingObject)
{
//Create the merge publication.
publication.Create();
// Create a Snapshot Agent job for the publication.
publication.CreateSnapshotAgent();
}
else
{
throw new ApplicationException(String.Format(
"The {0} publication already exists.", publicationName));
}
}
catch (Exception ex)
{
//Implement custom application error handling here.
throw new Exception(String.Format("The publication {0} could not be created.", publicationName), ex);
}
finally
{
conn.Disconnect();
}
but at this line
publicationDb.EnabledTransPublishing = true;
i am getting error -" An exception occurred while executing a Transact-SQL statement or batch."
So please help me out from this problem ..
waiting for your answers..
You Probably have you answer by now but for those who might be asking the same question. Its because you are using an express version of SQL Server and Publisher/distributors cannot be created in any version of SQl Server Express.
The instance you have in your code there is not a valid instance hence the exception is thrown.
take a look at:
http://msdn.microsoft.com/en-us/library/ms151819(v=sql.105).aspx
and the lines that say
Microsoft SQL Server 2008 Express can serve as a Subscriber for all types of replication, providing a convenient way to distribute data to client applications that use this edition of SQL Server. When using SQL Server Express in a replication topology, keep the following considerations in mind:
SQL Server Express cannot serve as a Publisher or Distributor. However, merge replication allows changes to be replicated in both directions between a Publisher and Subscriber.
Blockquote
I've got a integration test that looks like this:
using (var tran = Connection.BeginTransaction(IsolationLevel.ReadUncommitted))
{
try
{
// Act.
var result = controller.Create(something);
// Assert.
Assert.IsNotNull(result);
}
catch (Exception exc)
{
Assert.Fail(exc.Message);
}
finally
{
tran.Rollback();
Connection.Close();
}
}
Now, in that Create method, i end up calling a stored procedure which returns multiple result sets.
Here's the code to call that SP:
var cmd = Database.Connection.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "exec dbo.MySP #SomeParam";
cmd.Parameters.Add(new SqlParameter { Value = "test", ParameterName = "SomeParam" });
using (var rdr = cmd.ExecuteReader()) <--- exception thrown here.
{
// code to read result sets.
}
I get the following exception:
System.InvalidOperationException: ExecuteReader requires the command to have a transaction when the connection assigned to the command is in a pending local transaction. The Transaction property of the command has not been initialized.
Which i guess makes sense, but i would have thought it would inherit the pending local transaction?
I previously had the above code open a new connection, but it just timed out due to an apparent lock the pending transaction had on certain tables, despite the read uncommitted isolation level.
Basically, i need to be able to have an integration test which:
Opens a transaction
Does some stuff, including saving some records to the db, then calling another stored procedure which accesses data which includes the newly created data
Rollback the transaction.
Any ideas guys?
This works:
using (new TransactionScope(TransactionScopeOption.Required,
new TransactionOptions
{
IsolationLevel = IsolationLevel.ReadUncommitted
}))
This doesn't:
using (var tran = Connection.BeginTransaction(IsolationLevel.ReadUncommitted))
{
Must have something to do with the fact that TransactionScope lives outside of the actual Connection, so it wraps all connections that are opened inside of it, whilst the former code opens the transaction with a specific connection.
Whenever an exception is thrown in CLR stored procedure called from a SSIS package, within a DTC transaction , the error returned to client (SSIS package) relates to DTC rather than the underlying exception.
Is it possible to have information for the underlying error returned to client?
Note: When stored procedure is run from SQL Server Management Studio, outside of distributed transaction, detailed information for underlying error is returned.
Error: Executing the query "StoredProcedure” failed with the following
error: “The Microsoft Distributed Transaction Coordinator (MS DTC) has
cancelled the distributed transaction”. Possible reasons: Problems
with the query, “ResultSet” property not set correctly, parameters not
set correctly, or connection not established correctly.
All code running on a single SQL Server 2008 instance.
SSIS Package
---> Sequence Container (TransactionOption = Required )
---> Execute SQL Task (ADO.NET Connection Manager, SQLClient DataProvider)
---> SQL Server CLR Stored Procedure (No exception handling code)
---> TransactionScope(TransactionScopeOption.Required)
Code Which Reproduces Issue
The following code illustrates the issue but differs from the scenario described in the title in that client is a C# console app rather than a SSIS package
CLR Stored Procedure
using System;
using System.Transactions;
public partial class StoredProcedures
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void ExceptionStoredProcedure()
{
using (TransactionScope scope = new TransactionScope())
{
throw new Exception(#"Test exception thrown from ""ExceptionStoredProcedure""");
}
}
};
C# Console App Client
using System;
using System.Data.SqlClient;
using System.Transactions;
namespace SQLCLRTester
{
class Program
{
static void Main(string[] args)
{
try
{
using (TransactionScope scope = new TransactionScope())
{
string connectionString = "Data Source=.; Initial Catalog=Experiments; Integrated Security=Yes";
using (SqlConnection noOpConnection = new SqlConnection(connectionString))
{
noOpConnection.Open();
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command =
new SqlCommand()
{
CommandText = "ExceptionStoredProcedure",
CommandType = System.Data.CommandType.StoredProcedure,
Connection = connection
};
connection.Open();
command.ExecuteNonQuery();
}
} scope.Complete();
}
}
catch (Exception ex)
{
Console.WriteLine("Exception caught: {0}", ex.Message);
}
}
}
}
Message Printed By Client
Exception caught: The Microsoft Distributed Transaction Coordinator (MS DTC) has cancelled the distributed transaction
Notes:
InnerException is null
If the transaction scope in either the C#
console app or in the CLR stored procedure is removed then a DTC
transaction is not created and the information for underlying error
is returned .
Found a workaround that uses SqlContext.Pipe.Send() thanks to links provided by
Bob Beauchemin (Partner, MVP). See code below.
Notes: SqlClient appends "information messages" sent by SQL Server to SqlException.Message so client code that uses SqlClient doesn't need to change
CLR Stored Procedure
using System;
using System.Transactions;
using Microsoft.SqlServer.Server;
using System.Data.SqlClient;
public partial class StoredProcedures
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void ExceptionStoredProcedure()
{
using (TransactionScope scope = new TransactionScope())
{
try
{
throw new Exception(#"Test exception thrown from ""ExceptionStoredProcedure""");
scope.Complete();
}
catch (Exception ex)
{
if (Transaction.Current.TransactionInformation.DistributedIdentifier != Guid.Empty)
SqlContext.Pipe.Send(ex.Message);
throw;
}
}
}
};
Message Printed By Client
Exception caught: The Microsoft Distributed Transaction Coordinator (MS DTC) has cancelled the distributed transaction.
Test exception thrown from "ExceptionStoredProcedure"
Possible Explanation
Based on article links found by Bob about DTC transaction abort and T-SQL TRY/CATCH I think the observed behaviour may unfold as follows:
Exception in transaction scope in CLR stored procedure causes a
transaction abort vote to be sent to DTC.
DTC sends an abort request to all enlisted resource managers
including SQL Server
SQL Server translates abort request into an attention signal to the
SQL Server session in which the CLR stored procedure is executing
Attention signal changes how SQL Server CLR hosting code treats with
unhandled CLR exception which in turn results in exception message
not being included in result returned to client
Links to articles:
http://connect.microsoft.com/SQLServer/feedback/details/414969/uncatchable-error-when-distributed-transaction-is-aborted
http://msdn.microsoft.com/en-us/library/ms179296(SQL.90).aspx