Is it possible to have two (or more) instances of a Hibernate session at the same time?
Yes you can have multiple sessions open at the same time BUT you SHOULD NOT SHARE THEM across threads as Session's are not thread safe. Here is the JavaDoc for Session.
It's very common in web applications to have multiple sessions working at same time. One thing you want to be careful about your commit strategy. You can either have last commit wins or some sort of versioning strategy in place to take care of data integrity.
Related
Suppose, I have an application deployed on 3 nodes and from each node, one thread is trying to fetch and update the same data record at the same time. Data can only be fetched and updated from the central database. A method that is making the database connection, is thread safe. In this scenario, Is it possible that data can be modified and lead to inconsistency? If yes, how can we solve this problem?
You're confusing several completely different things together:
In general, to protect "data" between "threads", one would use a "lock". One way of protecting data in Java is with synchronized.
In general, a "thread" running on one "node" cannot - and will not - interfere with in-memory data objects being manipulated by some thread on a different "node".
"Database access" brings completely different issues to the table. In particular, read up about isolation levels
Finally, IF you're doing "database updates" and IF "concurrency" is an issue ... then you probably want to perform your update(s) within a DB transaction.
A "transaction" is ACID:
Atomic
Consistency
Isolation
Durability
I've got a problem with understanding the details of thread safety in Hibernate.
I know that Hibernate Sessions are not by themselves thread safe, so I'm not going to access them from more than one thread. However, I can't find any information on the thread safety of Hibernate entities. Can I modify them in multiple threads, while they remain attached to the Session which was used to load them?
I won't be using lazy loading (I know it would lead to concurrency problems).
Entities will be properly synchronized and hibernate will access them via synchronized getters.
The scenario that I've envisioned:
Use a Hibernate Session to load entity A from database,
Subsequently, modify entity A from multiple threads, other than the thread in which the entity was loaded,
All the time entity A remains attached to the
Session and is in persistent state,
Flush the Session so that modifications are synchronized with the database.
Entity A remains attached to the Session, so the cycle can repeat, with further modification and flushing.
That depends on the nature of the modifications. If you modify an entity by creating, persisting and associating another entity with it in another thread, then it will not work, because the other entity instance will be considered detached in the first thread.
Taken aside the use cases like the one above, this should work in theory and only if you don't use bytecode instrumentation for the dirty check. Hibernate will just check whether the objects are dirty when they need to be flushed; basically, it does not care how you modified the objects.
However, this is not recommended.
Firstly, it may not be compatible with future versions of Hibernate/JPA (there may be more restrictions preventing concurrent access to the entities).
Secondly, the workaround is fairly simple: Just make the DTOs for the data that you want to modify concurrently, submit it for processing, and update the entities when the processing is done. This way the code is more clear, there are no unexpected Hibernate thread-related complaints and you keep the flexibility to use other useful features like lazy-loading.
Hibernate entities are tightly integrated with the session and I'm pretty confident, that if the session isn't thread safe, the entities aren't either.
Even without considering the session, entities are just java beans which aren't thread safe. If you for example
Set a reference from anA to anB in one thread and change a property of anA in a second thread (or persist the entity) there is no guarantee, that the second thread will ever see the changes from the first.
So NO: Hibernate Entities are not thread safe.
Our app is mostly using optimistic locking using Hibernate’ s versioning support. We are planning to implement pessimistic locking in one particular scenario. I don’t have much experience with pessimistic locking so please excuse if this question sounds naïve.
When a user shows intention for updating an entry - we lock the corresponding DB row using “select for update”. Now, if this user takes a long time to commit his changes are forgets about it after locking, how do we unlock this lock using some timeout/rollback mechanism? So that the row doesn’t stays locked for a very long time and disallowing all other users to edit it.
I doubt if this will be handled at Weblogic-JTA-Spring transaction mechanism we are using – where we already have a transaction timeout of 30 mins. (??)
So, should this rollback be handled directly at Oracle level. If yes, then how? Please advise on best way to handle this so that such locks don’t stay lingering around for too long.
Locks will be released only when the transaction ends. The transaction will end either when an explicit commit or rollback is issued to the database or when the database session is terminated (which does an implicit rollback). If your middle tier is already set to rollback any transactions that are open for more than 30 minutes, that would be sufficient to release the locks.
If you have a Java application running in a Weblogic application server, however, it strikes me as unusual for pessimistic locking to be appropriate. First, I assume that you are using a connection pool in the middle tier. If that is the case, then one database connection from the connection pool would need to be held by the middle tier for the length of the transaction (up to 30 minutes in this case). But allowing one session to hold open a particular database session for an extended period of time defeats the purpose of having a connection pool. Normally, dozens if not hundreds of application sessions can share a single connection from the connection pool-- if you are going to allow pessimistic locking, you're now forcing a 1:1 relationship between application sessions and database sessions for those sessions.
There are numerous cases that optimistic locking cannot replace pessimistic locking. Lock timeout is handled in the database. Refer to this page about how to configure it in Oracle
Can Oracle's default object lock timeout be changed?
This may be a very old, many times asked question. But I am not able to find a proper answer to it, so asking again.
For the database connections, we always use a singleton object. When the database is being accessed by thousands of users, how does the performance is maintained? I mean if there are thousands of requests per second, how the database connection is managed since we are using a singleton? Are the database requests serialized? Or a singleton is not used in these cases?
I know it is a kind of dumb question, but I am seriously confused. If anyone can give some reference reading link, it will be nice.
Thanks.
I'm not sure whether you've confused the use of a plain singleton with a service locator. Both of them are design patterns. The service locator pattern is used by applications to ensure that there is a single class entrusted with the responsibility of obtaining and providing access to databases, files, JMS queues, etc.
Most service locators are implemented as singletons, since there is no need for multiple service locators to do the same job. Besides, it is useful to cache information obtained from the first lookup that can be later used by other clients of the service locator.
By the way, the argument about
"it's to ensure that there is always only one active connection to your DB"
is false and misleading. It is quite possible that the connection can be closed/reclaimed if left inactive for quite a long period of time. So caching a connection to the database is frowned upon. There is one deviation from this argument; "re-using" the connection obtained from the connection pool is encouraged as long as you do so with the same context, i.e. within the same HTTP request, or user request (whichever is applicable). This done obviously, from the point of view of performance, since establishing new connections can prove to be an expensive operation.
i recommend to use connection poolinghttp://www.java2s.com/Code/Java/Database-SQL-JDBC/PooledConnectionExample.htm
Even though you haven't put anything about sessions/transactions/ORM, I think your question comes from Hibernate, JPA or other ORM background.
As such, for any transaction to happen, we need an entityManager or session. These sessions could be created for each transaction.
Now by using factory pattern, we can get as many similar objects as we want... But the factory itself should be singleton. So in DB operations, the entityManagerFactory or sessionFactory objects are kept as singletons.
When you think about it, it makes sense because after all a sessionFactory represents a configuration(DB, UserID, password, connection pool size, caching, etc). What you need to perform DB transaction is not the factory but the object(session) created by the factory. These you can have as many as you want. But if you have multiple factories, it just is unnecessary creation of same (similar) objects.
We use connection pooling in plain jdbc as well as ORM.
If your database connection creating singleton is stateless (which it should be, or at least should be immutable), its pretty simple.
When your web application is accessed by thousands of users simultaneously, there are actually thousands of threads, one per user. Each thread has its own Program Counter which keeps track of what instruction thread is currently processing. When a thread would access a public method of your singleton, for example myDBConnectionManager.getConnection(), it would start executing instructions specified within. Therefore, it is a thread that is actually creating a database connection by reading instructions specified in myDBConnectionManager.getConnection() method. The methods of singleton are only manuals that instruct threads what to do.
This way, your application can create millions of connections at the same time with a singleton as long as it is able to create millions of threads simultaneously.
What is 'Extended Session Antipattern' ?
An extended (or Long) session (or session-per-conversation) is a session that may live beyond the duration of a transaction, as opposed to transaction-scoped sessions (or session-per-request). This is not necessarily an anti-pattern, this is a way to implement Long conversations (i.e. conversations with the database than span multiple transactions) which are just another way of designing units of work.
Like anything, I'd just say that long conversations can be misused or wrongly implemented.
Here is how the documentation introduces Long conversations:
12.1.2. Long conversations
The session-per-request pattern is
not the only way of designing units of
work. Many business processes require
a whole series of interactions with
the user that are interleaved with
database accesses. In web and
enterprise applications, it is not
acceptable for a database transaction
to span a user interaction. Consider
the following example:
The first screen of a dialog opens. The data seen by the user has been
loaded in a particular Session and
database transaction. The user is free
to modify the objects.
The user clicks "Save" after 5 minutes and expects their
modifications to be made persistent.
The user also expects that they were
the only person editing this
information and that no conflicting
modification has occurred.
From the point of view of the user, we
call this unit of work a long-running
conversation or application
transaction. There are many ways to
implement this in your application.
A first naive implementation might
keep the Session and database
transaction open during user think
time, with locks held in the database
to prevent concurrent modification and
to guarantee isolation and atomicity.
This is an anti-pattern, since lock
contention would not allow the
application to scale with the number
of concurrent users.
You have to use several database
transactions to implement the
conversation. In this case,
maintaining isolation of business
processes becomes the partial
responsibility of the application
tier. A single conversation usually
spans several database transactions.
It will be atomic if only one of these
database transactions (the last one)
stores the updated data. All others
simply read data (for example, in a
wizard-style dialog spanning several
request/response cycles). This is
easier to implement than it might
sound, especially if you utilize some
of Hibernate's features:
Automatic Versioning: Hibernate can perform automatic optimistic
concurrency control for you. It can
automatically detect if a concurrent
modification occurred during user
think time. Check for this at the end
of the conversation.
Detached Objects: if you decide to use the session-per-request pattern,
all loaded instances will be in the
detached state during user think time.
Hibernate allows you to reattach the
objects and persist the modifications.
The pattern is called
session-per-request-with-detached-objects.
Automatic versioning is used to
isolate concurrent modifications.
Extended (or Long) Session: the Hibernate Session can be disconnected
from the underlying JDBC connection
after the database transaction has
been committed and reconnected when a
new client request occurs. This
pattern is known as
session-per-conversation and makes
even reattachment unnecessary.
Automatic versioning is used to
isolate concurrent modifications and
the Session will not be allowed to be
flushed automatically, but
explicitly.
Both
session-per-request-with-detached-objects
and session-per-conversation have
advantages and disadvantages. These
disadvantages are discussed later in
this chapter in the context of
optimistic concurrency control.
I've added some references below but I suggest reading the whole Chapter 12. Transactions and Concurrency.
References
Hibernate Core Reference Guide
12.1.2. Long conversations
12.3. Optimistic concurrency control