EntityManager connection - eclipselink

I am new to java. I have created my own development framework for dealing with entities depending on EntityManager. My problem is I want to get the sql connection reference used by EntityManager instance to execute additional database DML operations such that these operations should be committed or rolled back whenever the EntityManager is committed or rolled back.
Regards;

To get the java.sql.Connection object for the EntityManager em use
Connection conn = em.unwrap(Connection.class);
This will work in EclipseLink, but not in Hibernate.

Related

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

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!

SQL Azure Database retry logic

I have implemented the following code for handling INSERT/UPDATE retry logic with exponential backoff when writing to an Azure Database.
static SqlConnection TryOpen(this SqlConnection connection)
{
int attempts = 0;
while (attempts < 5)
{
try
{
if (attempts > 0)
System.Threading.Thread.Sleep(((int)Math.Pow(3, attempts)) * 1000);
connection.Open();
return connection;
}
catch { }
attempts++;
}
throw new Exception("Unable to obtain a connection to SQL Server or SQL Azure.");
}
However should I consider applying retry logic for my database reads as well? Or would the SqlCommand.CommandTimeout() method suffice? Most of my reads are instituted using the following code:
Dim myDateAdapter As New SqlDataAdapter(mySqlCommand)
Dim ds As New DataSet
myDateAdapter.Fill(ds, "dtName")
It's hard to know what sort of transient errors will occur in a production environment with Azure so I am trying to do as much mitigation as possible now.
I think retries are going to be part of your Windows Azure SQL Database operations in general.
Rather than implementing a custom solution, have you looked at the transient fault handling application block published by Microsoft Patterns and Practices, specifically for SQL Database?
Connection failures in SQL Azure are common. This is because your application will create a connection pool but while your side thinks these connections are over, Azure could terminate them at their end and you will never know about it.
They do this for valid reasons such as a particular instance has become overloaded and they are transferring connections to another one. With in-house SQL servers you generally never get this problem because your SQL Servers are always available and dedicated for your use.
As an example, I get about 5 connection failures with SQL Azure on about 100,000 database queries in a day.
It's going to happen with SQL Azure. If you are using ADO.NET then David's suggestion of transient fault handling is the way to go.
If you are going to use Entity Framework, there is good news and bad news: Transient Fault Handling with SQL Azure using Entity Framework
I have implemented SqlConnection and SqlCommand extension methods providing retry logic. It is available on NuGet.

NHibernate 3 - TransactionScope vs. NHibernate transactions

I need to choose between TransactionScope or NHibernate transactions for my new project.
What is better? When should use TransactionScope? NHibernate transactions?
They are different things.
You should always do your work inside a NHibernate transaction.
You can use TransactionScope as needed, for example. to use distributed transactions when there's more than one session involved.
NHibernate transactions will automatically enlist in distributed transactions, but they won't be created automatically, so the recommended pattern is: if you have a TransactionScope, open the NH transaction inside it.
Transaction management is exposed to the application developer via the NHibernate
ITransaction interface. You aren’t forced to use this API—NHibernate lets you
control ADO.NET transactions directly.

Connect NHibernate to different databases with same schema

We are in the process of splitting our db into several smaller ones. The schemas will be exactly the same and we will control which db the system connects to when the client logs in. I receive an error if I do not set a connection string in my nhibernate configuration. I do not want to create a factory for each db. Is it possible to have a session factory provide a Session that I can set the connection string before using it?
Have not used it but there is a method ChangedDatabase on the Session.Connection. Maybe that would work?
Maybe you can use NHibernate.Shards, in the NHcontrib repository

How to Insert into NHibernate DB after NHibernate Session

Let's say if I encounter an error in NHibernate db update, and when such an exception is thrown, I want to log it in the log table in the db, via NHibernate again.
Now, since I can't reuse NHibernate session after an exception thrown, I will get an error when I log into the log table. How to best handle this situation?
Open a new session.
Or use a logging framework like log4net with ADO.NET appender and do it completely separately out of NHibernate environment.
IMO logging should be a cross cutting concern of your application. You should not try to reuse the same session in order to log errors. NHibernate already uses log4net. All you need is to configure an appender that will write logs to the SQL database.