MSDTC Cancelling EntityFramework Transaction - entity-framework-6

We have an issue where MSDTC is cancelling a transaction from EntityFramework(EF) but unable to find a solution.
ERROR
System.Data.Enity.Core.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. ---> System.Data.SqlClient.SqlException: The Microsoft Distributed Transaction Coordinator (MS DTC) has cancelled the distributed transaction.
Essentially EF is executing a stored procedure on Server A however the stored procedure on Server A also takes data from another server - Server B
I should add this started failing with this error when the stored procedure on server A was amended and transactions to server B were added.
Is this possible under EF? If so, how can we get this to work.
We have tried:
Amending SQL server account permissions for the connection account
Changing MSDTC timeout config settings

Related

Cannot open database requested by login

I have a SQL Server 2008 R2 Express database.
I have written a Delphi application that uses a TADOConnection object to connect to the database. It works just fine on my computer. It fails to connect from other computers on the network.
It gives the error message:
Cannot open database "PeopleNetLink" requested by the login.
I have found all sorts of questions about this error message. I have found none that used SQL Server authentication and worked on one computer and not on others.
My connection string is
Provider=SQLNCLI10.1;
Integrated Security="";
Persist Security Info=False;
User ID=PNetLink;
Initial Catalog=PeopleNetLink;
Data Source=W1CNVS02\SQLEXPRESSPAY12;
Use Procedure for Prepare=1;
Auto Translate=True;
Packet Size=4096;
Initial File Name="";
Use Encryption for Data=False;
Tag with column collation when possible=False;
MARS Connection=False;
DataTypeCompatibility=0;
Trust Server Certificate=False;
Server SPN=""
Further experimentation reveals that if I log on to another computer as an admin, the program will log in successfully. This tells me that it is not using the user ID specified in the connect string. Now the question is "why not?"
This is a bit of a long-shot, as I don't have Sql Server 2008 installed, only the 2014 version. And maybe you've tried this already, but I spent hours on this problem before I found the step I was missing.
Assuming a utility like MS's PortQry shows the server's local network firewall is open and that your edition of 2008 comes with a copy of Sql Server Management Studio installed:
Start SSMS on the server,
Right-click the Sql Server's Properties
In the Properties pop-up, click the Connections tab
Check the checkbox "Allow remote connections to this server."
In some Sql Server editions, "Allow remote connections ..." is not check by default, which seems to square with marc_s's comment.
Update: Regarding your added "This tells me that it is not using the user ID specified in the connect string.":
If you open the DFM as text and hand-edit the connection string so that the "User ID" has a completely bogus value, then go back to the connection string builder, you should find two things:
The Enter information to log on to server reverts to Use a specific user name and password, so if you then click Test connection, the test unsurprisingly fails.
If you then select Use Windows NT Integrated security and click Test connection again, the test succeeds.
From 2., it is evident that the "User ID" in the connection string is ignored when using Windows authentication. That doesn't seem surprising to me, since the point of using Windows authentication is that the credentials used are those of the logged-in Windows user. You've already established that if you log in on the other computer as an admin (I assume you mean a Windows administrator account), the connection succeeds, so I'd have thought that the non-admin account needs to be added to the Sql Server's recognised users if you're wanting to connect using that ID (though I confess it's not at all clear to me whether you're actually trying to connect using Windows authentication of a specific Sql Server account).
If you're still stuck try using e.g. the Microsoft OLE DB Driver for SQL Server instead of the SQL Server Native Client. You might also single-step through this article:
https://social.msdn.microsoft.com/Forums/en-US/523c7b7e-6216-4790-87cb-945f3c1f4c5e/can-not-connect-to-microsoft-sql-server-express-2012?forum=sqlexpress
Also, google
sql server express 2008 remote "secpol.msc"
and note articles such as this one
https://social.msdn.microsoft.com/forums/sqlserver/en-US/1f5221bf-f5c3-4307-836b-a4f9dc07f02f/very-strange-remote-connection-issues

How do I return trigger error back to breezejs client side?

Validation can happen on client side and server side, what if it happens on db side, if I want to stop an insert/update by rollback in trigger, how do I notify the client side, now it seems breezejs just ignore my error raised in trigger.
If you are using an Entity Framework or NHibernate backed server, then throwing any exception on the server should fail the entire transaction and turn into a failed save on the client ( with all changes placed back into their 'presave' state). In order for this to occur the Breeze server must detect an exception. You may need to have your trigger to raise an exception.
If you are using some other server, the behavior depends on whether the database supports tranactional semantics. ( for example MongoDB does not).
Found it does return, just need set severity to higher and parse error message from http data.

Stored Proc access multiple databases on same server FAILS

I am trying to run stored procedure from a limited permission login that has been granted execute permissions for said stored procedure. The stored procedure access 2 databases that exist on the same server. When I execute the stored procedure I receive an error that states:
The server principal "LimitedUser" is not able to access the database "Database2" under the current security context.
Some background:
I have recently been tasked with the goal of migrating our 2 different database servers into a single database. I have backed up and exported the necessary databases and restored them into the new server. The older databases are MS sql server 2000 (for Database 2), and MS sql server 2005 (for database 1 - where the aforementioned stored proc is located)
I have found some leads that seem to suggest that because I imported the databases, the owners were different and that would cause a problem. So i ran "exec sp_changedbowner 'sa'" on the 2 databases to ensure they had the same owner. I still got the same error when running the stored proc from the LimitedUser. A lot of other examples on various forum sites deal with databases that are on different servers...and having to utilize open query commands. I do not believe this is necessary.
When I run it as a user who has more admin permissions, the stored proc runs just fine. So my question is, what permissions should I be setting to allow this action from LimitedUser?
Thanks!
LimitedUser needs permissions on Database2 to do whatever the stored procedure is doing in that database, ownership chaining will only work within the same database (unless you enable the server option Cross Database Ownership Chaining, which I don't recommend as it breaks down the database container as a security boundary).
So, for example, you have db1 and db2, there is a stored proc in db1 that executes select * from db2.dbo.table1
For this you need LimitedUser to have:
execute permissions in the db1 database for the procedure
select permissions on table1 in db2

TADOQuery SQL.add() submitting/preparing the sql

Overview:
I have written an application that allows a user to define a query, submit it to a server and view the results. The software can run on DB2 or MySQL.
Problem:
We've had issues in the DB2 version where a user has tried to run a query, and found that it has failed because their user profile has been disabled. In order to run a query on DB2 (on an IBM i), the user's profile name and password are provided in the connection string. Security on the server can specify that a user's profile is disabled after two or three incorrect logins.
Question:
I've debugged the application and found that the problem is down to the query being submitted twice. If the user's password is wrong, then of course, this is having the knock-on effect of disabling their profile.
On further inspection, when I've inspected the logs on the server (while debugging line by line), I've found that the query is submitted to the server when you call TADOQuery.sql.add(), and again when the TADOQuery's active propery is set to true (which is the point at which I would expect the query to be submitted to the server). Here's an example of the code that I'm using to run the query:
adoqry.active := false;
adoqry.sql.clear;
adoqry.sql.add('SELECT * FROM SOMEDB.SOMETABLE');
adoqry.active := true;
My question is therefore quite simple:
1. Why does the TADOQuery.sql.add() method submit the query (when it should just be adding the sql to the TADOQuery's sql property)?
2. What can I do to prevent this? i.e. is there any way to prevent the sql being submitted when I call the add() method?
For those of you that would like extra information about the logs, the exit point logs on the IBM i show that when I call adoqry.sql.add in the above example, the query is run through the "Database Server-SQL Requests" exit point application, via function "Prepare and Describe". When I call adoqry.active := true in the above example, the same query goes through the same exit point application, but via the "Open/Describe" function.
If you're not familiar with the IBM i, don't worry about it - I'm just including that information as proof that I have traced the query being submitted twice. The real issue is with the TADOQuery's sql.add() processing.
From your description of your problem, I assume you specify the ConnectionString of the ADOQuery. Doing this combines the database login with the running of the query. You have found that this has undesirable side effects when the user's credentials are invalid.
Separate the database login from the query by using an ADOConnection. Specify the ConnectionString of the ADOConnection and assign the ADOConnection to the ADOQuery.Connection property. This way, you control the database login and can catch logins with bad credentials. Additionally the ADOConnection.Open method allows you to specify the username and password so you do not have to put them in the ConnectionString.
While this does not answer you specific questions, this approach will help you solve the problem of the user's profile being disabled by separating the login from the running of the query.

Oracle error occurred, but error message could not be retrieved from Oracle

There is a delphi application in which I am trying to connect to Oracle database Using provider MSDAORA.1 but problem is coming in connecting. Oracle error message which is coming is "Oracle error occurred, but error message could not be retrieved from Oracle"
I am able to connect to database with Oracle10g client.
Connection String: Provider=MSDAORA.1;
User ID=murat;
Password = murat;
Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp) (HOST= INGPSP)(PORT=1521))(CONNECT_DATA=(SID=INGPSP)));
Persist Security Info=False;
Please provide your expert opinion what can be the reason of this?
The service name seems to be lacking in your address.
Set a tnsnames.ora file, and use the entry as data source instead of the data_source parameter you set. Follow the steps available on the faq.
Or use use connection strings like '//host[:port]/[service_name]' for your data source: //INGPSP:1521/ServiceName
For Oracle, both Microsoft and Oracle OleDB providers are known to have issue with BLOBs. If you can, use another mean of connection.
What I see that is strange is that your HOST and SID are the same. The HOST is the name of the machine on your network and the SID is the database instance on that machine. I created the following ConnectionString for the PRD3 database on machine DB19 (there are multiple databases on DB19) on our network. I was able to connect to the database successfully with real User ID and Password.
Provider=MSDAORA.1;
Password=123456;
User ID=abc;
Data Source="(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=db19)(PORT=1521))(CONNECT_DATA=(SID=prd3)))";
Persist Security Info=True
Normally the Data Source I use is the database name as defined in TNSNAMES.ORA. It is a lot less to type (fewer potential errors) and can be changed to another database without recompiling the program (such as switching between a development database and production database).

Resources