Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 327 Vote(s) - 3.48 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Do you need a database transaction for reading data?

#1
When I try to read data from the database, at least using

`((Session)em.getDelegate()).createCriteria()`

an exception is throws saying that a transaction is not present.

When I add the annotation:

@Transactional(
value = SomeClass.TRANSACTIONAL_MANAGER,
propagation = Propagation.SUPPORTS,
readOnly = true
)

it works fine.

However, since reading will happen million of times per second to access and read data, I want to make sure that our environment is not clogged up unnecessarily.

**If not, what is the cost of creating a read-only `Propagation.Supports` transaction?**

Can I not create a Hibernate Criteria Query without a transaction, in combination with Spring?



Reply

#2
Accoring to my experience with **JPA** implementation in **J2EE**, a **Transaction manager** is always needed in order to perform **CRUD** operation safety, by guaranteeing a rollback in order to preserve data integrity.

> Enterprise applications use different resources to save data and send messages like a database or message queue. If we want to query these resources sequentially and to cancel the whole operation once a problem occurs, we have to put this query in a unit of work so that will be executed as a whole.

You could define it:

- by using related annotations (as shown in the questions); in this way, the container loads automatically the transaction manager for a given persistence context;

- by injecting manually the transaction manager, as follows:

public class sample {

@PersistenceContext
EntityManager em;

// Injected transaction manager
@Inject
UserTransaction utx;

private static final String[] GAME_TITLES = {
"Super Mario Brothers",
"Mario Kart",
"F-Zero"
};

private void clearData() throws Exception {
utx.begin();
em.joinTransaction();
System.out.println("Dumping old records...");
em.createQuery("delete from Game").executeUpdate();
utx.commit();
}

private void insertData() throws Exception {
utx.begin();
em.joinTransaction();
System.out.println("Inserting records...");
for (String title : GAME_TITLES) {
Game game = new Game(title);
em.persist(game);
}
utx.commit();
// clear the persistence context (first-level cache)
em.clear();
}

// ...

}

**Spring Data**, as JPA-spec implementation, may follow the same approach.

You could find more information by reading the following article: **[Java_Persistence/Transactions][1]**.


[1]:

[To see links please register here]

Reply

#3
All database statements are executed within the context of a physical transaction, even when we don’t explicitly declare transaction boundaries (BEGIN/COMMIT/ROLLBACK).

If you don't declare transaction boundaries, then each statement will have to be executed in a separate transaction (`autocommit` mode). This may even lead to opening and closing one connection per statement unless your environment can deal with connection-per-thread binding.

Declaring a service as `@Transactional` will give you one connection for the whole transaction duration, and all statements will use that single isolation connection. This is way better than not using explicit transactions in the first place.

On large applications, you may have many concurrent requests, and reducing database connection acquisition request rate will definitely improve your overall application performance.

JPA doesn't enforce transactions on read operations. Only writes end up throwing a [`TransactionRequiredException`][2] in case you forget to start a transactional context. Nevertheless, it's always better to declare transaction boundaries even for read-only transactions (in Spring `@Transactional` allows you to mark read-only transactions, which has a great performance benefit).

Now, if you use declarative transaction boundaries (e.g. `@Transactional`), you need to make sure that the database connection acquisition is delayed until there is a JDBC statement to be executed. In JTA, this is the default behavior. When using RESOURCE_LOCAL, you need to set the [`hibernate.connection.provider_disables_autocommit`][3] configuration property and make sure that the underlying connection pool is set to disable the auto-commit mode.


[2]:

[To see links please register here]

[3]:

[To see links please register here]

Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through