Introduction to the @Transactional working principle of Spring Framework

Source: Internet
Author: User
Tags bind requires thread

Recent projects have paid special attention to spring's @Transactional, so look it up on the Internet.

This article will delve into the transaction management of spring. This paper mainly introduces how the @transactional works at the bottom. The following articles will describe what traps are used for using transactions for attributes such as propagation (transactional propagation) and isolation (isolation) and how to avoid JPA and transaction management

It is important that JPA itself does not provide any type of declarative transaction management. If JPA is used outside of the dependency injection container, transaction processing must be implemented by the developer.

1 2 3 4 5 6 7 8 9 10 11-12 UserTransaction UTX = Entitymanager.gettransaction ();            try {utx.begin ();            Businesslogic ();      Utx.commit ();          catch (Exception ex) {utx.rollback ();      Throw ex; }

This way of transaction management enables the transaction scope to be clearly expressed in the code, but it has the following drawbacks: Easy to duplicate code and error any error can have a large impact error difficult to debug and reproduce reduces the readability of the code base if the method calls other transaction methods how to handle it. using spring @Transactional

Using the spring @Transactional, the code above is simplified to:

1 2 3 4 @Transactional public void Businesslogic () {... Use Entity manager inside a transaction ...}

The code is simpler and more readable, and is the recommended way to handle transactions in spring.

By using @transactional, transactional propagation and many other important aspects can be handled automatically. In this case, if Businesslogic () invokes another transaction method, the method determines how to join the running transaction, depending on the option.

A potential drawback to this powerful mechanism is that it hides the underlying runtime, which is difficult to debug when it doesn't work properly. @Transactional meaning

One of the key points about @transactional is to consider two separate concepts, each with its own scope and lifecycle: persistence context (persistent contexts) database transaction (transaction)

The @Transactional itself defines the scope of a single transaction. This transaction is within the scope of the persistence context.

The persistence context in JPA is Entitymanager, and the internal implementation uses the hibernate session (using Hibernate as the persistent provider).

The persistence context is just a synchronization object that records the state of a finite set of Java objects and ensures that the changes to those objects are ultimately persisted to the database.

This is a very different concept from a single transaction. A entity Manager can be used across multiple transactions , and it does. Entitymanager When to span multiple transactions.

The most common scenario is when the application uses the open session in view mode to handle lazy initialization exceptions, and the previous article describes the advantages and disadvantages of this approach.

In this case, multiple queries running in the view layer are in separate transactions, rather than business logic for single transactions, but these queries are managed by the same entity manager.

Alternatively, the developer marks the persistence context as persistencecontexttype.extended, which means it can respond to multiple requests. How to define the relationship between Entitymanager and transaction.

This is chosen by the application developer, but the most common approach to JPA Entity Manager is "Entity Manager per application Transaction" (each transaction has its own entity manager) pattern. The common methods for Entity manager injection are:

1 2 @PersistenceContext Private Entitymanager em;

This defaults to "Entity Manager per transaction" mode. In this mode, if the entity Manager is used internally within the @transactional method, the method will run in a single transaction. how @PersistenceContext work.

The ensuing problem is how @persistencecontext injects entity manager only when the container is started, assuming the entity manager lifecycle is short-lived and requires multiple entity manager per request.

The answer is that it cannot: Entitymanager is an interface that is injected into the spring bean not entity the manager itself, but rather the context aware proxy of the specific entity manager at run time (contextual-aware proxy).

The specific class used for the proxy is Sharedentitymanagerinvocationhandler, which can be confirmed by the debugger. So how does @transactional work.

The persistent context broker that implements the Entitymanager interface is not the only part of declarative transaction management, and in fact contains three components: the slicing transaction manager for the Entitymanager proxy itself transaction

Look at the three parts and how they interact with each other. facets of a transaction

The slice of a transaction is a "around" slice that can be invoked before and after the business method of the annotation. The concrete class that implements the slice is transactioninterceptor.

The slice of a transaction has two primary responsibilities: in ' before ', the slice provides an invocation point to determine whether the invoked business method should run within the scope of the transaction in progress or start a new stand-alone transaction. In ' after ', the slice needs to be determined that the transaction is committed, rolled back, or continues to run.

At ' before ', the transaction section itself does not contain any decision logic, and whether the decision to start a new transaction is delegated to the transaction manager is completed. transaction manager

The transaction manager needs to address the following two issues: whether the new entity manager should be created. Whether a new transaction should be started.

These require that the transaction slice ' before ' logic be invoked when decided. The decision of the transaction manager is based on the following two points: whether the transaction is in the propagation attribute of the transaction method (for example, Requires_new always starts a new transaction)

If the transaction manager is determined to create a new transaction, it will: Create a new Entity Manager Entity manager bind to the current thread get a connection from the database connection pool bind the connection to the current thread

Use the threadlocal variable to bind both the Entity manager and the database connection to the current thread.

When transactions are run they store threads, and when they are no longer in use, the transaction manager decides whether to purge them.

Any part of the program that requires the current Entity manager and database connection can be retrieved from the thread. Entitymanager Proxy

Entitymanager Proxy (previously introduced) is the last part of the puzzle. This is not called directly by entity Manager when the business method calls Entitymanager.persist ().

Instead, the business method calls the proxy, which gets the current entity manager from the thread, which is described earlier in the transaction manager binding entity Manager to a thread.

Looking at the various parts of the @transactional mechanism, let's take a look at the common spring configurations that implement it. Consolidate three parts

How to combine three parts to make a transaction annotation work correctly. First define the Entity manager factory.

This allows entity Manager proxy to be injected through persistent context annotations.

1 2 3 4 5 6 7 8 9 10 11 12 13 14-15 16 @Configuration      public class Entitymanagerfactoriesconfiguration {    & nbsp;    @Autowired          private DataSource DataSource;            @Bean (name = "Entitymanagerfactory")           public Localcontainerentitymanagerfactorybean emf () {              Localcontainerentitymanagerfactorybean emf = ...               Emf.setdatasource (DataSource);              Emf.setpackagestoscan (                  New string[] {"Your.package" });              Emf.setjpavendoradapter (                  new HibernateJpaVendorAdapter ());              return EMF;         }     }

The next step is to implement a section that configures the transaction manager and applies the transaction in the class of the @transactional annotation.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16-17 @Configuration      @EnableTransactionManagement      public class transactionmanagersconfig {         @Autowired           entitymanagerfactory emf;          @Autowired          Private DataSource DataSource;            @Bean (name = "TransactionManager")           public Platformtransactionmanager TransactionManager () {              Jpatransactionmanager TM =                   new Jpatransactionmanager ();                  Tm.setentitymanagerfactory (EMF);                  Tm.setdatasource (DataSource);              return TM;         }     }

Note @enabletransactionmanagement notifies spring that classes @Transactional annotations are surrounded by the facets of the transaction. So the @transactional can be used. Summary

The Spring declarative transaction management mechanism is very powerful, but it can be misused or prone to configuration errors.

It is helpful to understand the internal work situation when the mechanism does not work properly or it does not meet the expected operational results.

The most important thing to remember is to take into account two concepts: Transaction and persistence contexts, each with a distinct lifecycle of its own that is unreadable.

Original link: Javacodegeeks translation: Importnew.com-hejiani
Translation Links: http://www.importnew.com/12300.html

This is a translation of the article, very good ah, feel good please top.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.