Why is this deadlocking? - jpa

Hi I am running into a deadlock in a JavaFX Application and I am not sure why this is happening...
When initializing my application I start a Thread to load a certain view that is creating an object that is extending my DatabaseManager. At the same time another Thread is doing the same on another view and another object that is extending the DatabaseManager.
The first thread that enters the following constructor enters the synchronized block but NEVER reaches the "System.out.println("****3");" line.
After this happened my later started thread enters the constructor and is of course blocked since the resource has never been released again.
by thread 1.
Any ideas, why this is resulting in a deadlock? I am using javafx.concurrent.Task with java.lang.Thread
public abstract class DatabaseManager {
protected static final AtomicReference<EntityManager> entityManager = new AtomicReference<>();
protected DatabaseManager() {
if (entityManager.get() == null) {
System.out.println("****1");
synchronized (entityManager) {
if (entityManager.get() == null) {
System.out.println("****2");
entityManager.set(Persistence.createEntityManagerFactory(
DatabaseConstants.hsqlPersistenceUnitName,
DatabaseConstants.getProperties()).createEntityManager());
System.out.println("****3");
}
}
}
}
...

AtomicReferences (and their primitive wrapper friends) manage their own atomicity. So, while I can't really see why this is deadlocking, using a synchronized block to use an AtomicReference defeats the entire purpose of the AtomicReference in the first place.
You can just do:
protected DatabaseManager() {
entityManager.compareAndSet(null,
Persistence.createEntityManagerFactory(
DatabaseConstants.hsqlPersistenceUnitName,
DatabaseConstants.getProperties()).createEntityManager());
}
which will have exactly the same effect as what you are trying to do (without the logging, obviously).
The recommended way to lazily initialize a static field is to use the "Lazy initialization holder class idiom":
public abstract class DatabaseManager {
protected static EntityManager getEntityManager() {
return EntityManagerHolder.entityManager ;
}
private static class EntityManagerHolder {
static final EntityManager entityManager =
Persistence.createEntityManagerFactory(
DatabaseConstants.hsqlPersistenceUnitName,
DatabaseConstants.getProperties()).createEntityManager() ;
}
}
}
This ensures lazy initialization, because the inner class DatabaseManager.EntityManagerHolder is not loaded until it is referenced for the first time, which doesn't happen until getEntityManager() is called for the first time. It is guaranteed atomic, because class initializers are guaranteed atomic. And furthermore, since the atomicity is enforced only when the inner class is initialized, the cost of synchronization is not incurred on subsequent calls to getEntityManager(). (By contrast, the solution with the AtomicReference performs a (presumably internally-synchronized) call to AtomicReference.compareAndSet(...) each time you create a new DatabaseManager.)
See Josh Bloch's Effective Java, item 71, for a fuller discussion.

I found the solution for my deadlock eventhough I do not know why this results in a deadlock...
I have just another thread that is trying to access another database. The application interacts with 2 databases. All performings on my HSQL database came from my DatabaseManager and while one thread was trying to initialize the EntityManager in my DatabaseManager the third Thread was simply calling
Persistence.createEntityManagerFactory(DBConstants.ORACLE_PERSISTENCE_UNIT).createEntityManager();
After removing that line and also using the DatabaseManager to establish the connection to the second database the deadlock was gone.
But I have no idea why. The only possible solution in my eyes is that eclipselink itself deadlocked there...

Related

Why JpaRepository doesn't commit to database when called from #SpringBootTest?

When repository.save(t) is called from my service, which is in turn called from my controller, all works just fine, and the object is inserted into the database table; But, when the service is called from my test class, Hibernate returns the created object but does not really flush the transaction into the database. I have tried using #Transactinal and #Commit in my test class and also on my #Test methods, but no difference in the result. I have also tried other solutions which involve using org.springframework.test.context.transaction.TestTransaction class, but any method call on this class throws an exception.
this is my super class for test:
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
#TestInstance(TestInstance.Lifecycle.PER_CLASS)
public abstract class QaApplicationTest {
protected abstract void initializeTest() throws Exception;
protected abstract void cleanupTestEffects() throws Exception;
}
And this is my concrete test class:
public class RequestControllerTest extends QaApplicationTest {
#Autowired
private SiteService siteService;
#Autowired
private RequestService requestService;
#Test
#Transactional
public void givenObject_whenInsertToDB_thenCreated() throws Exception{
Site siteObject = siteService.save(siteObject); //Here I need a commit.
Request request = new Request(site.getId());
Request savedRequest = requestService.save(request); //Here database returns "Parent Key Not Found" error.
Assertions.assertTrue(savedRequest.getId()>0);
}
}
I know the #Transactional on test methods are used to roll back all the changes made inside the method, however, In my case, the changes are not even committed in the first place. And I have used #org.springframework.transaction.annotation.Transactional which is the correct annotation. I don't know which part I am doing wrong! Any idea?
My colleague found the issue; we had used a third-party library (Camunda) that had enabled batch-insert on Hibernate. So by disabling the batch operation the issue was resolved and the insert is actually taking place now. Not sure, why we faced this only in Spring Test and not in the main application though. if anyone has a comment, we appreciate it.

Making sure JPA commits my transaction before another service accesses the data

It feels so simple:
I have a ViewScoped bean (JPA2 + EE6 + Seam3, if that matters) where the user of the web application can invoke a method like this:
public void save() {
doEntityManagerStuff(); // manipulates data in the database
callRemoteWebservice(); // which is to read said data and propagate it to other systems
}
Unfortunately, save() starts a transaction at the opening curly bracket and doesn't commit it before the closing bracket, meaning that the new data is not available to the remote web service to read.
I have tried to explicitly extract and annotate the database work:
#TransactionAttribute(REQUIRES_NEW)
private void doEntityManagerStuff() {
blabla(); // database stuff
}
But that didn't have any impact at all. (Maybe because that's EJB stuff and I'm running on seam...?)
The only thing that worked for me so far was to inject #UserTransaction and force commit the transaction at the end of either save() or doEntityManagerStuff() but that felt incredibly dirty and dangerous.
The other alternative would be to turn off container-managed transactions for the entire project, but that means I'd have to make all my beans manage their transactions manually, just so I can make this one case work.
Is there a better way?
To answer my own question:
I only went half-way, and that's why it didn't work. I didn't know enough about EJBs and their boudaries, and naively though just annotating the doEntityManagerStuff(...) method with a transaction attribute in my view-scoped CDI/Seam bean would be enough.
It isn't.
When I moved said method into a separate, stateless EJB, injected that into my CDI/Seam bean and called it from there, everything worked as expected.
#Stateless
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class MyPersister {
...
public void doEntityManagerStuff() {
blabla(); // database stuff
}
...
}
and
#ViewScoped
public class MyWebsiteBean {
...
#Inject MyPersister persister;
...
public void save() {
persister.doEntityManagerStuff(); //uses its own transaction
callRemoteWebService();
}
...
}

Singleton pattern using PHP

I am trying to create a dynamic navigation class.
class myApp_Helper_Breadcrum{
protected $navigationArray=array();
private static $_instance = null;
public static function getInstance()
{
if (!isset(self::$_instance)) {
self::$_instance = new self();
}
return self::$_instance;
}
private function __construct() {
$this->navigationArray = array();
}
public function popin($popInElement){
array_push($this->navigationArray,$popInElement);
}
public function displayLinks()
{
//print array
}
}
In boostrap I did following
$nlinks=myApp_Helper_Breadcrum::getInstance();
Zend_Registry::set('nlinks',$nlinks);
Now in my controller I am calling as follow
$nlinks= Zend_Registry::get('nlinks');
$nlinks->popin('Home');
$nlinks->displayLinks();
The problem is, even if this class is singleton the constructor is called again and again which makes my array to initialize. what I am trying to achieve is to keep pushing the items in the navigation array as I navigate the site.
Any idea why it is like this in ZF?
PHP isn't running like Java would where you have a JVM to maintain the state of your classes. In Java you can have a singleton behave exactly as you describe, but in PHP all the classes are refreshed with each subsequent call to the web server. So your singleton will stay in place for the duration of that call to the server, but once the response is sent then you start over again on the next call.
If you want to maintain state through successive calls you need to use the $_SESSION to keep track of your state.
EDIT:
My answer above deals with PHP in general and not the Zend Framework specifically. See my comment below.
Try to define your component as below:
class MyApp_Helper_Breadcrum
{
private static $_instance = null; // use private here
public static function getInstance()
{
if (self::$_instance === null) { // use strictly equal to null
self::$_instance = new self();
}
return self::$_instance;
}
private function __construct() // use private here
{
// ...
}
// ...
}
I ran into the exact same problem.
The problem is that the persistence of your classes are on the request scope.
And with zend, you can even have multiple requests for a page load.
PHP is a shared nothing architecture; each
request starts in a new process, and at the end of the request, it's all
thrown away. Persisting across requests simply cannot happen -- unless
you do your own caching. You can serialize objects and restore them --
but pragmatically, in most cases you'll get very little benefit from
this (and often run into all sorts of issues, particularly when it comes
to resource handles).
You may want to use Zend_cache, for persistence
Even though this is old, I would like to add my 2 cent.
Zend DOES NOT create a singleton, that persists across multiple requests. Regardless of the interpretation of the ZF documentation, on each request, the whole stack is re-initialized.
This is where your problem comes from. Since bootstrapping is done on each request, each request also re-initializes your helper method. As far as I know, helpers in ZF 1.x CAN'T be singletons.
The only way I see this being implementes ar you want it to be, is using sessions.

Entity Framework + Autofac - Random errors on save

Using autofac as my IoC framework.
I'd like to be able to set up my DbContext instance in my application's startup.
In my ASP.NET MVC 3 project, I register DbContext instance in Global.asax (PerLifetimeScope). But when I fire up my site on multiple browsers (or multiple tabs) at once, sometimes I get Object reference not set to an instance of an object. or New transaction is not allowed because there are other threads running in the session when I try to save changes back to database. Also I get
ExecuteReader requires an open and available Connection. The connection's current state: Broken. sometimes when I want to read data from database.
the errors seem to pop up randomly and I suspect it has something to do with my context's lifetime scope. here's my DbContext's overriden SaveChange method.
public class MyContext : DbContext
{
public override int SaveChanges()
{
var result = base.SaveChanges(); // Exception here
}
}
Here's how I register my context:
builder.Register(c => new MyContext("SomeConnectionString"))
.InstancePerLifetimeScope();
If I just have one open tab of my site in the browser everything works ok.
Also, It's worth mentioning I have CRUD operations with db every 5-10 seconds in my website by calling a controller method using Ajax.
StackTrace for New transaction is not allowed because there are other threads running in the session:
at System.Data.EntityClient.EntityConnection.BeginDbTransaction(IsolationLevel isolationLevel)
at System.Data.EntityClient.EntityConnection.BeginTransaction()
at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
at System.Data.Entity.DbContext.SaveChanges()
at MyProject.Data.MyContext.SaveChanges() in D:\Test.cs
StackTrace for Object reference not set to an instance of an object.:
at System.Data.Objects.ObjectStateManager.DetectConflicts(IList`1 entries)
at System.Data.Objects.ObjectStateManager.DetectChanges()
at System.Data.Entity.Internal.InternalContext.DetectChanges(Boolean force)
at System.Data.Entity.Internal.InternalContext.GetStateEntries(Func`2 predicate)
at System.Data.Entity.Internal.InternalContext.GetStateEntries()
at System.Data.Entity.Infrastructure.DbChangeTracker.Entries()
at System.Data.Entity.DbContext.GetValidationErrors()
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
at System.Data.Entity.DbContext.SaveChanges()
at MyProject.Data.MyContext.SaveChanges() in D:\Test.cs at
Registration of MyContext looks ok. Is it possible that some other service that takes a MyContext is registered as a singleton and being shared across threads?
I had the same issue, sporadic errors related to the DbContext while using Autofac to resolve the DbContext.
{System.Data.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details.
etc.
{System.NullReferenceException: Object reference not set to an instance of an object.
at System.Data.Objects.ObjectStateManager.DetectConflicts(IList`1 entries)
etc.
I found a class resembling the following in my code. The dependency resolution was occurring within a static method inside of the singleton. The object being resolved had a dependency on the DbContext. I haven't had any additional issues after I found a way to restructure this class so that it was no longer a singleton.
Perhaps you have a similar situation? Another thing to try might be to make your DbContext InstancePerHttpRequest. That could help identify whether this is the issue.
public class Singleton
{
private static Singleton _instance = new Singleton();
private Singleton()
{
}
public static void DoSomething<TSource>(TSource source) where TSource : ISource
{
var items = DependencyResolver.Current.Resolve<IEnumerable<IDbContextConsumer<TSource>>>();
foreach (var item in items)
{
item.Execute(source);
}
}
}

Variables in GWT server side code

I'm fairly new to GWT and have never worked with Java Servlets before. I know how to make RPCs but I was wondering if there are any concurrency issues with declaring member variables in my RPC's ServiceImpl/RemoteServiceServlet class. I.e. From multiple "simultaneous" RPCs overwriting the same variable, similar to what happens with threads when a variable isn't declared volatile.
I also need to use an extra thread in my server side code, so I was wondering if there's any problems (outside of the usual thread safety problems) with declaring some of the servlet's members as static so the other thread can access the variables without a reference to the servlet instance. Is it possible for more than one instance of the same RemoteServiceServlet class to be running at the same time?
E.g.
public class MyServiceImpl extends RemoteServiceServlet implements MyService {
// Which of these variable declarations are a bad idea in a servlet?
private String someVariable;
private static String anotherVariable;
volatile private static String multiThreadedVariable;
public void init() { ... }
...
}
Thanks.
A Servlet is a singleton, therefore there is only one instance of the MyServiceImpl class. By introducing these state variables you will run into thread-safety issues not because there might be more than one MyServiceImpl instance, but because there is only one instance that will service ALL of your requests. Unless you synchronize access to these variables, you will have thread-safety issues, so I recommend removing them completely (most likely you don't even need them).