Spring transaction isolation level and propagation mechanism, spring + mybatis + atomikos for Distributed Transaction Management, mybatisatomikos
This article is reproduced in. It must follow four principles (ACID ). 2. Transaction type 3. Spring transaction isolation level: spring has five isolation levels, which are defined in the TransactionDefinition interface. From the source code, we can see that its moisolation_default (default level of the underlying database) is consistent with the four other isolation levels.
The difference between phantom read and non-repeated read: phantom read focuses on insertion and deletion, that is, the second query will find less or more data than the first query, so that it gives an illusion, the repeatable reading focuses on modification, that is, the second query will find that the query results are inconsistent with the first query results, that is, the first results cannot be reproduced.
The higher the database isolation level, the higher the execution cost, and the lower the concurrent execution capability. Therefore, you must consider it comprehensively during actual project development. In order to consider the concurrency performance, you generally use the committed read isolation level, it can avoid loss of updates and dirty reads. Although repeated and Phantom reads cannot be avoided, pessimistic or optimistic locks can be used to solve these problems when possible.
Pessimistic lock and optimistic lock can be referred to: http://blog.csdn.net/liaohaojian/article/details/62416972
4. Propagation Behavior: there are seven propagation behaviors, which are also defined in the TransactionDefinition interface. 5. Spring transaction support
1. spring provides many built-in transaction managers that support different data sources. There are three common categories:
- DataSourceTransactionManager: Under the org. springframework. jdbc. datasource package, the data source transaction management class provides transaction management for a single javax. SQL. DataSource data source, as long as it is used for JDBC and Mybatis framework transaction management.
- HibernateTransactionManager: org. springframework. orm. under the hibernate3 package, the data source transaction management class provides for a single org. hibernate. sessionFactory supports transaction management when integrating with the Hibernate framework. Note: This Transaction Manager only supports Hibernate3 + and Spring3.0 + only supports Hibernate 3.2 +;
- JtaTransactionManager: located at org. springframework. transaction. the jta package provides support for Distributed Transaction Management, delegates transaction management to the Java EE application server, or customizes a local JTA Transaction Manager, which is nested into the application.
The built-in Transaction Manager inherits the abstract class AbstractPlatformTransactionManager, and AbstractPlatformTransactionManager inherits the interface PlatformTransactionManager.
The core of Spring framework's support for transaction management is the Transaction Manager abstraction. for different data access frameworks, the policy interface PlatformTransactionManager is implemented to support transaction management of the multi-clock data access framework.
The PlatformTransactionManager interface is defined as follows:
Public interface PlatformTransactionManager {TransactionStatus getTransaction (TransactionDefinition definition) throws TransactionException; // returns an activated transaction or creates a new transaction (determined by the transaction attribute defined by the TransactionDefinition parameter ), the returned TransactionStatus object represents the status of the current transaction. The TransactionException (not checked exception) thrown by this method indicates that the transaction failed for some reason. Void commit (TransactionStatus status) throws TransactionException; // used to submit the transaction represented by the TransactionStatus parameter. Void rollback (TransactionStatus status) throws TransactionException; // used to roll back the transaction represented by the TransactionStatus parameter .}
The TransactionDefinition interface is defined as follows:
Public interface TransactionDefinition {int getPropagationBehavior (); // return the defined transaction Propagation Behavior int getIsolationLevel (); // return the transaction isolation level int getTimeout (); // return the defined transaction timeout boolean isReadOnly (); // return whether the defined transaction is a read-only String getName (); // return the transaction name}
The TransactionStatus interface is defined as follows:
Public interface TransactionStatus extends SavepointManager {boolean isNewTransaction (); // returns whether the current transaction is a new transaction boolean hasSavepoint (); // returns whether the current transaction has a storage point void setRollbackOnly (); // set the transaction rollback boolean isRollbackOnly (); // set whether the current transaction should roll back void flush (); // used to refresh the changes in the underlying session to the database, it is generally used to refresh sessions such as Hibernate/JPA, which may have no impact on transactions such as JDBC; boolean isCompleted (); // return whether the transaction is completed}
2. Spring Distributed Transaction Configuration
- By referencing the JNDI data source of an Application Server (such as Tomcat), JTA transaction management is indirectly implemented and dependent on the application server.
- Direct Integration of JOTM (Official Site: http://jotm.objectweb.org/), Atomikos (Official Site: https://www.atomikos.com/) to provide JTA Transaction Management (no application server support, often used in unit testing)
- Use the application server-Specific Transaction Manager and advanced features of JTA transactions (Weblogic, Websphere)
1). Reference The JNDI data source of the Application Server (such as Tomcat) to indirectly implement JTA transaction management. The configuration is as follows:
<Beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns: jee = "http://www.springframework.org/schema/jee" xsi: schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd"> <! -- JNDI data source --> <jee: jndi-lookup id = "dataSource" jndi-name = "jdbc/test"/> <! -- JTA transaction Manager --> <bean id = "txManager" class = "org. springframework. transaction. jta. JtaTransactionManager"> <! -- TransactionManagerName specifies the JNDI name of the JTA Transaction Manager to delegate transaction management to the transaction manager --> <property name = "transactionManagerName" value = "java: comp/TransactionManager "/> </bean> </beans>
2) use Atomikos for Distributed Transaction Management. The configuration is as follows:
<? Xml version = "1.0" encoding = "UTF-8"?> <Beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns: p = "http://www.springframework.org/schema/p" xmlns: aop = "http://www.springframework.org/schema/aop" xmlns: tx = "http://www.springframework.org/schema/tx" xmlns: context = "http://www.springframework.org/schema/context" xmlns: task = "http://www.springframework.org/schema/task" xsi: schemaLocation = Http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-3.0.xsdhttp://www.springframework.org/schema/taskhttp://www.springframework.org/schema /Task/spring-task-3.0.xsdhttp: // container "> <context: component-scan base-package =" com. suicai. *. service. impl "/> <context: component-scan base-package =" com. suicai. util "/> <! -- The configuration file loaded by this method is only used in xml, but the tool classes are annotated --> <bean class = "org. springframework. beans. factory. config. propertyplaceholderpolicer "> <property name =" location "value =" classpath: conn. properties "/> </bean> <! -- Only annotations are supported. You cannot use the properties file in the xml configuration to use the SPEL expression in the class to load the corresponding value. --> <bean id = "temp" class = "org. springframework. beans. factory. config. propertiesFactoryBean "> <property name =" locations "> <array> <value> classpath: public. properties </value> </array> </property> </bean> <bean id = "abstractXADataSource" class = "com. atomikos. jdbc. atomikosperformancebean "init-method =" init "destroy-method =" close "abstract =" true "> <property nam E = "borrowConnectionTimeout" value = "60"/> <! -- Get the maximum waiting time for Failed Connections. If a connection is available within this time period, --> <property name = "reapTimeout" value = "20"/> <! -- Maximum data acquisition time. If this value is not set, Atomikos uses the default value of 5 minutes. If this value is not set, it takes more than 5 minutes to process massive data reads, an error similar to Resultset is close will be thrown. --> <property name = "maintenanceInterval" value = "60"/> <! -- Connection recovery time --> <property name = "loginTimeout" value = "60"/> <! -- Java database connection pool, maximum waiting time for obtaining datasouce --> <property name = "logWriter" value = "60"/> <property name = ""> </property> <property name = "minPoolSize "value =" 1 "/> <! -- Minimum connections retained in the connection pool --> <property name = "maxPoolSize" value = "3"/> <! -- Maximum number of connections retained in the connection pool --> <property name = "maxIdleTime" value = "60"/> <! -- Maximum idle time. connections are dropped if they are not used within 60 seconds. If it is 0, it will never be discarded. Default: 0 --> </bean> <! -- Configure two data sources mysql --> <bean id = "ds_suicai" parent = "abstractXADataSource"> <! -- UniqueResourceName indicates a unique resource name. multiple data sources cannot be repeated. --> <property name = "uniqueResourceName" value = "suicaifortest"/> <! -- XaDataSourceClassName is implemented by a specific Distributed Data Source vendor. --> <property name = "xaDataSourceClassName" value = "com. mysql. jdbc. jdbc2.optional. MysqlXADataSource"/> <! -- XaProperties attribute specifies the database attributes of a specific manufacturer --> <property name = "xaProperties"> <props> <prop key = "URL" >$ {db. jdbcUrlOne} </prop> <prop key = "user" >$ {user} </prop> <prop key = "password" >$ {password} </prop> </ props> </property> </bean> <bean id = "ds_kaizhi" parent = "abstractXADataSource"> <! -- UniqueResourceName indicates a unique resource name. multiple data sources cannot be repeated. --> <property name = "uniqueResourceName" value = "puildingpurchasefortest"/> <! -- XaDataSourceClassName is implemented by a specific Distributed Data Source vendor. --> <property name = "xaDataSourceClassName" value = "com. mysql. jdbc. jdbc2.optional. MysqlXADataSource"/> <! -- XaProperties attribute specifies the database attributes of a specific manufacturer --> <property name = "xaProperties"> <props> <prop key = "URL" >$ {db. jdbcUrlTwo} </prop> <prop key = "user" >$ {user} </prop> <prop key = "password" >$ {password} </prop> </ props> </property> </bean> <! -- Dynamically configure the data source --> <bean id = "cece2" class = "com. suicai. common. datasource. dynamicDataSource "> <property name =" targetDataSources "> <map key-type =" java. lang. string "> <entry value-ref =" ds_suicai "key =" ds_suicai "> </entry> <entry value-ref =" ds_kaizhi "key =" ds_kaizhi "> </entry> </map> </property> <property name = "defaultTargetDataSource" ref = "ds_suicai"> </property> </bean> <bean id = "sqlSessionFacto RyBeanA "class =" org. mybatis. spring. SqlSessionFactoryBean "> <! -- Specify the data source --> <property name = "dataSource" ref = "ds_suicai"/> <! -- Specify the configuration file of mybatis --> <property name = "configLocation" value = "classpath: mybatis. cfg. xml "/> </bean> <bean id =" sqlSessionFactoryBeanB "class =" org. mybatis. spring. sqlSessionFactoryBean "> <! -- Specify the data source --> <property name = "dataSource" ref = "ds_kaizhi"/> <! -- Specify the configuration file of mybatis --> <property name = "configLocation" value = "classpath: mybatis. cfg. xml"/> </bean> <! -- CustomSqlSessionTemplate inherits SqlSessionTemplate to override the getSqlSessionFactory method. For more information, see <bean id = "sqlSessionTemplate" class = "com. suicai. util. customSqlSessionTemplate "scope =" prototype "> <constructor-arg ref =" sqlSessionFactoryBeanA "/> <property name =" targetSqlSessionFactorys "> <map> <entry value-ref =" sqlSessionFactoryBeanA "key = "ds_suicai1"> </entry> <entry value-ref = "sqlSessionFactoryBeanB" key = "ds_ka Izhi1 "> </entry> </map> </property> </bean> <! -- Configure atomikos Transaction Manager --> <bean id = "atomikosTransactionManager" class = "com. atomikos. icatch. jta. userTransactionManager "init-method =" init "destroy-method =" close "> <property name =" forceshudown "value =" true "/> </bean> <bean id =" atomikosUserTransaction "class =" com. atomikos. icatch. jta. userTransactionImp "> </bean> <! -- Configure spring transaction manager --> <bean id = "transactionManager" class = "org. springframework. transaction. jta. jtaTransactionManager "> <property name =" transactionManager "> <ref bean =" atomikosTransactionManager "/> </property> <property name =" userTransaction "> <ref bean =" atomikosUserTransaction "/> </property> <! -- This parameter must be set. Otherwise, JtaTransactionManager does not support custom isolation levels by default --> <property name = "allowCustomIsolationLevels" value = "true"/> </bean> <tx: advice id = "advice" transaction-manager = "transactionManager"> <tx: attributes> <! -- REQUIRED: a transaction is REQUIRED. If not, create a --> <tx: method name = "save *" propagation = "REQUIRED"/> <tx: method name = "creat *" propagation = "REQUIRED"/> <tx: method name = "add *" propagation = "REQUIRED"/> <tx: method name = "update *" propagation = "REQUIRED"/> <tx: method name = "delete *" propagation = "REQUIRED"/> <! -- Supported. If yes, no --> <tx: method name = "*" propagation = "SUPPORTS"/> </tx: attributes> </tx: advice> <aop: config> <aop: pointcut expression = "execution (* com. suicai. *. service. impl. *. *(..)) "id =" pointcut "/> <! -- The link between tx and aop is the complete declarative transaction configuration --> <aop: advisor advice-ref = "advice" pointcut-ref = "pointcut"/> </aop: config> <! -- Uses the packet scanning mechanism to automatically register all dao in the specified package --> <bean class = "org. mybatis. spring. mapper. MapperScannerConfigurer"> <! -- Note sqlSessionTemplate injection --> <property name = "sqlSessionTemplateBeanName" value = "sqlSessionTemplate"/> <property name = "basePackage" value = "com. suicai. *. dao "/> </bean> <bean id =" viewResolver "class =" org. springframework. web. servlet. view. internalResourceViewResolver "> <property name =" viewClass "> <value> org. springframework. web. servlet. view. internalResourceView </value> </property> <! -- Jsp directory --> <property name = "prefix"> <value>/</value> </property> <! -- Jsp file suffix --> <property name = "suffix"> <value>. jsp </value> </property> </bean> <! -- Verification code --> <bean id = "captchaProducer" class = "com. google. code. kaptcha. impl. defaultKaptcha "> <property name =" config "> <bean class =" com. google. code. kaptcha. util. config "> <constructor-arg> <props> <prop key =" kaptcha. border "> no </prop> <prop key =" kaptcha. border. color "> 105,179, 90 </prop> <prop key =" kaptcha. textproducer. font. color "> red </prop> <prop key =" kaptcha. image. width "> 200 </prop> <prop key =" kaptcha. textproducer. font. size "> 60 </prop> <prop key =" kaptcha. image. height "> 80 </prop> <prop key =" kaptcha. session. key "> code </prop> <prop key =" kaptcha. textproducer. char. length "> 4 </prop> <prop key =" kaptcha. textproducer. font. names ">,, </prop> </props> </constructor-arg> </bean> </property> </bean> <bean id = "messageSource" class = "org. springframework. context. support. reloadableResourceBundleMessageSource "> <property name =" basename "value =" classpath: messages "/> <property name =" fileEncodings "value =" UTF-8 "/> <property name =" cacheSeconds "value =" 120 "/> </bean> </beans>
Download path of required packages and related configuration files for atomikos: bytes.