NullPointerException happening intermittently with Hibernate criteriaQuery - database

I am working on a springboot application in a multi-threading environment where I am using Hibernate with javax.persistence.EntityManager to access database. I have separate HikariPools for read and write queries.
Here, the multiple threads while doing read operation from database (all the read queries) are using a single read connection (since I have autowired the entityManager and not using PersistanceContext). And similarly multiple threads will write to db as well with the help of writeEntityManager where a single connection is being used by all of the threads.
I am facing an issue with AbstractLockUpgradeEventListener.upgradeLock . This is happening intermittently and could not find the exact root cause for this.
Few assumptions:-
DB utilization touches 100%.( That might give an edge to this issue)
Lock is applied before executing any write query and threads are getting starved if one thread takes more than enough time
Can anyone suggest something here w.r.t design or implementation strategy or on what could be the actual root cause.
This only happens once in a while

The Hibernate EntityManager is not thread-safe, you must not use it from multiple threads.
In fact the EntityManager AND the objects loaded must not be used from multiple threads
https://discourse.hibernate.org/t/hibernate-and-multithreading/289

Related

Solr multicore issue with locking

The issue I have is locking on both indexes.
To explain, when constructing the EmbeddedSolrServer server I have to parse the CoreContainer and the core name and so I have constructed two seperate instances of the EmbeddedSolrServer, one for each core. Now I essentially do this (example code):
serverInstanceOne.add(document);
serverInstanceTwo.add(document) // This fails to obtain a lock
If serverInstanceOne is purely targeting core1, why does it create a lock in the index of core2?
Is there a way to prevent this? Or a way of forcing the server to drop the lock without shutting down each time?
I have tried to find in the Solr documentation an explanation around this behaviour but am at a loss still. Essentially I am using multicore and have a spring batch job, which is using the EmbeddedSolrServer to pump data overnight into some indexes.

How to work with database and UI under threads?

I am interested in make better programs with more responsive design and capabilities. Nowadays, when I create my programs that access data remotely, my interface freezes and there is no animated GIF to work on that condition.
I was told by David Hefferman that animated GIF that are created in the VCL do not respond even in threads because the VCL is in the main thread, and the same goes to databases.
My doubt here is how to work with threads, specifically in databases, so I have lots of questions about it.
Do I have to implement my entire database in thread functions and procedures?
If that is correct, then I can't use database by dropping components to the Form, right?
But what about the user input and grids? Will they work correctly with those threads or will I have to user regular TEdit instead of TDBEdit to then send it's content to a insert/update sql command?
The main objective in here is to create Delphi application that access remote databases like MySQL using Zeos but not freezing for every drop of consult made in the server. At least the smaller ones. It would be very ugly if the system were to download a list of records to a table and the user could still input things. For those cases I would like very much that my animated GIF (or other solutions) could work.
Thank you for any help at all!
In my experience, the best approach is to drop your database components on a Data module and then create this data module dynamically in each thread. Database components typically work fine if they are created and initialized in the thread that is using them.
There are, however, caveats - if you are connecting to a Firebird database, you should make sure that only one thread at the time is establishing a connection. (Use a critical section around the code that connects to the database.) This holds for Firebird 1.5, 2.0 and 2.1 but may not be necessary anymore for Firebird 2.5 (I didn't yet have opportunity to test it).
EDIT (in answer to EASI's comment): Yes, connecting to a database can take some time. If you frequently need to execute short operations, it is best to keep threads connected and running for a longer period of time.
I can think of two ways to do that. 1) Keep threads alive and connected and run a message loop inside. This loop would receive commands from the main thread, process them and return a result. 2) Keep threads initialized and connected in a thread pool and activate them when you need to perform a database operation.
Basically, both approaches are the same, the difference is in the level which handles 'receive and process command' loop.
The second approach can be easily implemented in the OmniThreadLibrary by using the IOmniConnectionPool.SetThreadDataFactory mechanism. See Adding connection pool mechanism to OmniThreadLibrary and demo 24_ConnectionPool for more information. Alternatively, you can use the high-level abstraction Background worker where you can establish database connection on a per-thread basis in a Task initialization block.

How to dispatch thousands of SQL requests asynchronously

We are writing a simple application:
build thousands of SQL select statements
run each select using BeginExecuteReader
put the results into another database
We've tried a few things that either leave connections in a SUSPENDED state (as verified by sp_who2), or take a much longer time to complete than just the SQL query itself (maybe some kind of deadlocking?).
We are:
calling EndExecuteReader in the callback handler.
calling conn.Close() and conn.Dispose()
recursively starting another call
public static void StartQuery() {
// build the query for array[i]
// ...
SqlConnection conn = new SqlConnection(AsyncConnectionString);
conn.Open();
cmd.BeginExecuteReader(CallbackHandler, cmd);
i++;
}
public static void CallbackHandler(IAsyncResult ar) {
// unpack the cmd
cmd.EndExecuteReader();
// read some stuff to a DataTable...
// SqlBulkCopy to another database (synchronously)
cmd.Connection.Close();
cmd.Connection.Dispose();
StartQuery();
}
Does anyone have recommendations or links on a robust pattern to solve this type of problem?
Thanks!
I assume you did set the AsyncronousProcessing on the connection string. Thousands of BeginExecute queries pooled in CLR is a recipe for disaster:
you'll be quickly capped by the max worker threads in the SQL Server and start experiencing long connection Open times and frequent time outs.
running 1000 loads in parallel is guaranteed to be much slower than running 1000 loads sequentially on N connections, where N is given by the number of cores on the Server. Thousands of parallel requests will simply create excessive contention on shared resources and slow each other down.
You have absolutely no reliability with thousands of requests queued up in CLR. If the process crashes, you loose all the work whitout any trace.
A much better approach is to use a queue from which a pool of workers dequeue loads and execute them. A typical producer-consumer. The number of workers (consumers) will be tuned by the SQL Server resources (CPU cores, memory, IO pattern of the loads) but a safe number is 2 times the number of server cores. Each worker uses a dedicated connection for it's work. the role of the workers and the role of the queue is not to speed up the work, but on the contrary, they act as a throttling mechanism to prevent you from swamping the server.
An even better approach is to have the queue persisted in the database, as a means to recover from a crash. See Using Tables as Queues for the proper way of doing it, since table based queuing is notoriously error prone.
And finally, you can just let SQL Server handle everything, the queueing, the throttling and the processing itself via Activation. See Asynchronous Procedure Execution and the follow up article Passing Parameters to a Background Procedure.
Which one is the proper solution depends on lots of factors you know about your problem, but I don't, so I can't recommend which way should you go.

NHibernate, the Parallel Framework, and SQL Server

hey guys, we have a loop that:
1.Loops over several thousand xml files. Altogether we're parsing millions of "user" nodes.
2.In each iteration we parse a "user" xml, do custom deserialization
3.finally, in each iteration, we send our object to nhibernate for saving. We use:
.SaveOrUpdateAndFlush(user);
This is a lengthy process, and we thought it would be a perfect candidate for testing out the .NET 4.0 Parallel libraries. So we wrapped the loop in a:
Parallel.ForEach();
After doing this, we start getting "random" Timeout Exceptions from SQL Server, and finally, after leaving it running all night, OutOfMemory unhandled exceptions.
I haven't done deep debugging on this yet, but what do you guys think. Is this simply a limitation of SQL Server, or could it be our NHibernate setup, or what?
cheers
andy
Parallel.ForEach is not magic. You still have to manage the units of work, connection pools, etc, with the added complexity of multiple threads. Also, remember that the NHibernate Session is not thread-safe (each thread should have its own session)
Your timeout exceptions could be caused by deadlocks or exhaustion of the connection pool (you didn't post the stack trace or the inner exceptions, so it's a guess)
OutOfMemory exceptions are probably due to memory leaks; you are probably leaving your sessions and entities hanging around. You should use a profiler like ANTS or dotTrace to find the cause (both have free trials)

Are there any local DB that support multi-threading?

I tried sqlite,
by using multi-thread, only one thread can update db at the same time..
I need multi-thread updating the db at same time.
Is there are any DB can do the job?
ps: I use delphi6.
I found that sqlite can support multi-threading,
But in my test of asgsqlite, when one thread inserting, others will fail to insert.
I'm still in testing.
SQLite can be used in multi-threaded environments.
Check out this link.
Firebird can be used in an embedded version, but it's no problem to use the standard (server) installation locally as well. Very small, easy to deploy, concurrent access. Works good with Delphi, you should look into it as an option.
See also the StackOverflow question "Which embedded database to use in a Delphi application?"
Sqlite locks the entire database when updating (unless this has changed since I last used it). A second thread cannot update the database at the same time (even using entirely separate tables). However there is a timeout parameter that tells the second thread to retry for x milliseconds before failing. I think ASqlite surfaces this parameter in the database component (I think I actually wrote that bit of code, all 3 lines, but it was a couple of years ago).
Setting the timeout to a larger value than 0 will allow multiple threads to update the database. However there may be performance implications.
since version 3.3.1, SQLite's threading requirements have been greatly relaxed. in most cases, it means that it simply works. if you really need more concurrency than that, it might be better to use a DB server.
SQL Server 2008 Express supports concurrency, as well as most other features of SQL Server. And it's free.
Why do you need multiple threads to update it at the same time? I'm sure sqlite will ensure that the updates get done correctly, even if that means one thread waiting for the other one to finish; this is transparent to the application.
Indeed, having several threads updating concurrently would, in all likelihood, not be beneficial to performance. That's to say, it might LOOK like several threads were updating concurrently, but actually the result would be that the updates get done slower than if they weren't (due to the fact that they need to hold many page locks etc to avoid problems).
DBISAM from ElevateSoft works very nicely in multi-threaded mode, and has auto-session naming to make this easy. Be sure to follow the page in the help on how to make it all safe, and job done.
I'm actually at the moment doing performance testing with a multi-threaded Java process on Sybase ASE. The process parses a 1GB file and does inserts into a table.
I was afraid at first, because many of the senior programmers warned me about "table locking" and how dangerous it is to do concurrent access to DB. But I went ahead and did testing (because I wanted to find out for myself).
I created and compared a single threaded process to a process using 4 threads. I only received a 20% reduction in total execution time. I retried the the process using different thread counts and batch insert sizes. The maximum I could squeeze was 20%.
We are going to be switching to Oracle soon, so I'll share how Oracle handles concurrent inserts when that happens.

Resources