How Spring @Transactional Works

Source: Internet
Author: User

This article will take a closer look at spring's transaction management. The main introduction @Transactional is how to work at the bottom. The following article will cover:

    • Use of attributes such as propagation (transactional propagation) and isolation (isolation)
    • What traps are used by transactions and how to avoid them
JPA and transaction Management

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

123456789101112 UserTransaction utx = entityManager.getTransaction();     try {         utx.begin();         businessLogic();        utx.commit();     } catch(Exception ex) {         utx.rollback();         throw ex;     }

Transaction management in this way enables a transaction scope to be clearly expressed in code, but it has the following drawbacks:

    • Prone to duplicate code and errors
    • Any error can have a greater impact
    • Errors are difficult to debug and reproduce
    • Reduces the readability of the code base
    • What if the method calls other transactional methods?
Use Spring @Transactional

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

1234 @Transactional    publicvoidbusinessLogic() {        ... use entity manager inside a transaction ...    }

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

Through use @Transactional , transaction propagation and many other important aspects can be automatically processed. In this case businessLogic() , if another transaction method is called, the method determines how to join the running transaction, depending on the options.

One potential disadvantage of this powerful mechanism is that it hides the underlying operation, which is difficult to debug when it does not work properly.

@TransactionalMeaning

About @Transactional , one of the key points is to consider two separate concepts, each with their own scope and life cycle:

    • Persistence context (persistence contexts)
    • Database Transaction (TRANSACTION)

@Transactionalitself defines the scope of a single transaction. This transaction is within the scope of the persistence context .

The persistence context in JPA is EntityManager that the internal implementation uses Hibernate Session (using hibernate as the persistence provider).

The persistence context is simply a synchronization object that records the state of a limited set of Java objects and ensures that changes to these objects are eventually persisted to the database.

This is a very different concept from a single transaction. An entity Manager can be used across multiple transactions , and this is really the case.

When does Entitymanager span multiple transactions?

The most common scenario is when an app 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 run by the view layer are in separate transactions, not single-transaction business logic, but these queries are managed by the same entity manager.

Another scenario is that the developer marks the persistence context as PersistenceContextType.EXTENDED , which means it can respond to multiple requests.

How do I define the relationship between Entitymanager and transaction?

This is selected by the app developer, but the most common way for JPA entity manager is "entity manager per application Transaction" (each transaction has its own entity manager) mode. The common methods for Entity manager injection are:

12 @PersistenceContext    privateEntityManager em;

The default is "Entity Manager per transaction" mode. In this mode, if @Transactional the entity Manager is used inside a method, the method runs in a single transaction.

How does @PersistenceContext work?

The problem with this is @PersistenceContext how to inject entity manager only when the container starts, assuming that the entity manager life cycle is short, and that multiple entity managers are required for each request.

The answer is that it cannot: EntityManager is an interface that is injected into the spring bean instead of the entity manager itself, but instead proxies the context awareproxy for the specific entity manager at runtime.

Typically the specific class used for the proxy is SharedEntityManagerInvocationHandler , with the debugger, to confirm this.

So how does @transactional work?

The EntityManager persistence context proxy that implements the interface is not the only part of declarative transaction management, and in fact contains three components:

    • Entitymanager Proxy itself
    • Facets of a transaction
    • Transaction manager

Take a look at the three parts and the interplay between them.

Facets of a transaction

The facet of a transaction is a "around" slice, which can be called before and after the annotated business method. The concrete class for implementing facets is TransactionInterceptor .

The facets of a transaction have two main responsibilities:

    • At ' before ', the facets provide a point of call to determine whether the invoked business method should run within the scope of the transaction in progress or start a new independent transaction.
    • At ' after ', the facets need to determine whether the transaction is committed, rolled back, or continues to run.

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

Transaction manager

The transaction manager needs to address the following two issues:

    • Should the new entity manager be created?
    • Should you start a new transaction?

These need to be determined when the transaction plane ' before ' logic is invoked. The decision of the transaction manager is based on the following two points:

    • Whether the transaction is in progress
    • The propagation property of the transaction method (such as REQUIRES_NEW always starting a new transaction)

If the transaction manager determines that a new transaction is to be created, then:

    • Create a new entity manager
    • Entity manager binds to the current thread
    • Getting connections from the database connection pool
    • Bind a connection to the current thread

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

Transactions run when they are stored in threads, and when they are no longer being used, the transaction manager decides whether to purge them.

Any part of the program can be fetched from the thread if it needs the current Entity manager and database connection.

Entitymanager Proxy

Entitymanager proxy (described earlier) is the last part of the puzzle. When a business method is called entityManager.persist() , this is not called directly by entity Manager.

Instead, the business method invokes the proxy, which obtains the current entity manager from the thread, which is described previously by the transaction manager binding the entity manager to the thread.

Understanding the @Transactional various parts of the mechanism, let's look at the common spring configurations that implement it.

Consolidation of three parts

How do you combine the three parts to make the transaction annotations work correctly? Define the Entity Manager factory first.

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

12345678910111213141516 @Configuration    public class EntityManagerFactoriesConfiguration {        @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 the configuration transaction manager and apply the facets of the transaction in the @Transactional annotated class.

1234567891011121314151617 @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;        }    }

Annotations @EnableTransactionManagement notify Spring that @Transactional the annotated class is surrounded by the facets of the transaction. This makes it @Transactional possible to use the.

Summarize

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

It is helpful to understand the internal work of the mechanism when it does not work properly or if it does not meet the expected running results.

The most important thing to remember is that there are two concepts to consider: the transaction and the persistence context, each with its own unreadable distinct life cycle.

How Spring @Transactional Works

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.