EF and TransactionScope for both SQL Server and Oracle without escalating/spanning to DTC? - sql

Can anyone update me on this topic?
I want to support both SQL Server and Oracle in my application.
Is it possible to have the following code (in BL) working for both SQL Server and Oracle without escalating/spanning to distributed transactions (DTC) ?
// dbcontext is created before, same dbcontext will be used by both repositories
using (var ts = new TransactionScope())
{
// create order - make use of dbcontext, possibly to call SaveChanges here
orderRepository.CreateOrder(order);
// update inventory - make use of same dbcontext, possibly to call SaveChanges here
inventoryRepository.UpdateInventory(inventory);
ts.Complete();
}
As of today, end of August 2013, I understand that it works for SQL Server 2008+ ... but what about Oracle? I found this thread... it looks like for Oracle is promoting to distributed transactions but is still not clear to me.
Does anyone have experience with writing apps to support both SQL Server and Oracle with Entity Framework to enlighten me?
Thanks!
Update: Finally I noticed EF6 comes with Improved Transaction Support. This, in addition to Remus' recommendations could be the solution for me.

First: never use var ts = new TransactionScope(). Is the one liner that kills your app. Always use the explicit constructor that let you specify the isolation level. See using new TransactionScope() Considered Harmful.
Now about your question: the logic not to promote two connections in the same scope into DTC relies heavily on the driver/providers cooperating to inform the System.Transactions that the two distinct connections are capable of managing the distributed transaction just fine on their own because the resource managers involved is the same. SqlClient post SQL Server 2008 is a driver that is capable of doing this logic. The Oracle driver you use is not (and I'm not aware of any version that is, btw).
Ultimately is really really really basic: if you do not want a DTC, do not create one! Make sure you use exactly one connection in the scope. It is clearly arguable that you do not need two connections. In other words, get rid of the two separate repositories in your data model. Use only one repository for Orders, Inventory and what else what not. You are shooting yourself in the foot with them and you're asking for pixie dust solutions.
Update: Oracle driver 12c r1:
"Transaction and connection association: ODP.NET connections, by default, detach from transactions only when connection objects are closed or transaction objects are disposed"

Nope, DTC is needed for distributed transactions - and something spanning 2 different database technologies like this is a distributed transaction. Sorry!

Related

Execute sql statement before normal execution with aop

I'm trying to create a Multitenant application with spring.
I'm trying to have a different schema for each Tenant on a PostgreSql database.
I first created a TenantAwareDataSource extending org.springframework.jdbc.datasource.AbstractDataSource where basically I manage a Map of org.apache.commons.dbcp.BasicDataSource, configuring setConnectionInitSqls() for each tenant. (The datasource the project had before was org.apache.commons.dbcp.BasicDataSource)
But then discussing it with a friend, we came up with the idea of changing the schema for every statment executed with an aspect (aop), simply adding a set search_path to statement just before normal execution.
This could greatly simplify the problems related to having too many connections to the database (a connection pool for every tenant at any given time).
Has anybody executed additional statements using AOP?
Any pitfalls to overcome?
I'm thinking on put back org.apache.commons.dbcp.BasicDataSource and intercept java.sql.Statements.exe*(..)
I'm not very experienced with Spring persistence. Or SQL statement execution interception for that matter (haha).
Is it ok?
I found this article but I don't think I need to obtain a reference for each connection.
Am I right?
Also found this one. The author is using org.springframework.jdbc.core.JdbcOperations. Not sure it's the case in my Spring Roo generated project.
Thank you all.

Two connections under one Transaction

I searched araound and having some difficulties in implementing one scenario with SQL Server 2000 and sybase.
I have two SQL servers on different locations naming ServerA (MSSQL Server) and ServerB (Sybase server).
I have a table called SALARY.
Whenever I insert one record to customer SALARY in ServerA, I also will insert it into ServerB.
If should any of them failed, both of them should be rolled back.
I am using Asp .Net with VB for the programming.
I do not have the right to change / add table in Server B. The only thing allowed in Server B is insert/delete/update record.
I looked around and find a method to use TransactionScope but I am not quite sure it is the right way to do.
Ref: http://msdn.microsoft.com/zh-tw/library/system.transactions.transactionscope%28v=vs.80%29.aspx
Please help. THANKS!!!!
IMHO, TransactionScope is the right approach. However, I'm unsure if Sybase supports the ability to enlist in ambient transactions.

NHibernate: Retrieve SQL to be executed as a string

From an ICriteria, is it possible to retrieve a string containing the SQL that NHibernate is planning on executing?
I know that is possible to receive a trace, but I was wondering if there is a method that can be called that generates the SQL (for example, so you don't have to actually flush to the database).
It's not directly exposed anywhere. Keep in mind the generated SQL is dialect, driver and batcher dependant, so generation of the final SQL occurs late in the pipeline.
NHibernate Profiler works great for us. there's a trial available at nhprof.com/
edit: NHProf attaches itself on the connection from your machine to the database and captures any SQL passing by, with the number of results and the time spent on fetching processing. NHProf also gives you all sorts of advice that will improve performance.

Groovy, How to do 2 phase commit? Is Sql.withTransaction can manage transaction scope accross multiple databases?

Well, I think my question says it all. I need to know if Groovy SQL supports two phase commits. I'm actually programming a Grails Service where I want to define a method which does the following:
Get SQL instance for Database 1,
Get SQL instance for Databsae 2,
Open a transaction some how:
Within the transaction call two different stored procedures on each database respectively.
Then commit some how or rollback on both connection if needed.
I didn't find any useful information yet about this anywhere on the web.
I've to program two phase commits any way, so even if this is supported by some other means (e.g. getting help from spring artifacts and use them in grails), please guide me. This has become a show stopper for me at the moment.
Note: I'm using MySQL and mysql-connector driver.
Thanks,
Alam Sher
The current version of MySQL seems to support two-phase commits as long as you're using the INNODB storage engine. There are other restrictions.
MySQL reference for two-phase commit
Groovy added "transaction support" in 1.7, but I'm not certain what they mean by that.

What ORMs are developers using to connect to Azure?

Im interested to find out what techniques developers are using to connect to a Windows Azure instance running in the cloud?
From what i understand it is very similar to SQL Server with two of the key differences being Multiple Active Recordsets are not supported and idle/long running connections are automatically terminated by azure. For this microsoft suggest incorporating retry logic in your application to detect a closed connection and then attempt to complete the interrupted action. Does any one have example code that they are currently using on this?
To build out the data layer i was looking at various ORMs. Since im going to be accessing azure from windows azure (ie seperate boxes) to me it would seem key that any ORM mapper would need to support asynchronous methods so as not to block any windows azure instances.
Any suggestions as to which ORM mapper to use, or comments on what you are currently using
I have successfully used NHibernate with Azure and we are in the process of building a commercial app on top of NHibernate. The only problem that I had was with the connection pools when running locally and connecting to SQL Azure in the cloud - which was fixed when turning connection pooling off.
You may find similar problems with other ORM's... SQL Azure is less patient (for obvious reasons) than most people are used to. Connections timeout quicker, recycle sooner and so on.
Test first!
Here's one specifically designed for Azure:
"Telerik recently announced the
availability of Open Access, the first
ORM that works seamlessly with SQL
Azure relational databases in the
Windows Azure cloud."
And a few commenters at the Azure User Group recommend LLBLGen and Entity Framework.
I've been using Entity Framework - runs without any problems, just a different connection string.
What you do have to think about is your connection strategy, and how efficient your queries are. I've got method that's easy to write in EF - I've got a new record that could be duplicated, so I check if it's there, and if not, add it.
EF makes it really easy to do this, as if you're just accessing a local collection. BUT ... if you're paying for your dB access because it's in Azure and not on your local network, hmm, maybe there's a better (aka cheaper) way of doing that
According to Ayende, NHibernate "just works" with SQL Azure.
We have been using NHibernate without any customization on Azure (indeed, it just works), you can check Lokad.Translate as an open source example of such use.