Heim >Datenbank >MySQL-Tutorial >Die Isolationsstufe der Spring-Transaktion, das Ausbreitungsverhalten und Spring+mybatis+atomikos realisieren eine verteilte Transaktionsverwaltung
Dieser Artikel bringt Ihnen den Inhalt über die Isolationsstufe von Spring-Transaktionen, das Ausbreitungsverhalten und die Implementierung einer verteilten Transaktionsverwaltung. Ich hoffe, dass er für Freunde in Not hilfreich ist Dir. Hilft.
Atomizität (Atomizität) : Das heißt, eine Transaktion ist eine unteilbare Mindestarbeitseinheit, und alle Vorgänge innerhalb der Transaktion werden entweder ausgeführt oder nicht ausgeführt ;
Konsistenz : Die Daten in der Datenbank befinden sich vor der Ausführung der Transaktion im richtigen Zustand und die Daten in der Datenbank sollten sich noch im richtigen Zustand befinden Nachdem die Transaktion abgeschlossen ist, d wenn das Geld von A überwiesen wird, B es aber nicht erhält, sonst sind die Daten in der Datenbank inkonsistent (falsch).
Isolation : Gleichzeitige Transaktionsausführungen haben keinen Einfluss auf andere Transaktionen. Dies erfordert die Isolationsstufe der Transaktionen
Dauerhaftigkeit (Dauerhaftigkeit) : Sobald eine Transaktion erfolgreich ausgeführt wurde, müssen ihre Änderungen an den Datenbankdaten dauerhaft sein und es können keine Dateninkonsistenzen oder Datenverluste auftreten aufgrund von: zum Beispiel Systemausfall oder Stromausfall.
Die Datenbank ist in lokale Transaktionen und globale Transaktionen unterteilt
Lokale Transaktionen: normale Transaktionen, unabhängig von einer Datenbank, die ACID für Operationen in der Datenbank garantieren können.
Verteilte Transaktionen: Transaktionen, an denen zwei oder mehr Datenbankquellen beteiligt sind, dh Transaktionen über mehrere Datenbanken desselben Typs oder heterogener Typen (bestehend aus lokalen Transaktionen jeder Datenbank), verteilt Der Zweck Der Zweck formaler Transaktionen besteht darin, die ACID aller Vorgänge dieser lokalen Transaktionen sicherzustellen, sodass Transaktionen mehrere Datenbanken umfassen können.
Java-Transaktionstypen sind in JDBC-Transaktionen und JTA-Transaktionen unterteilt
JDBC-Transaktion: Es handelt sich um die lokale Transaktion in der oben erwähnten Datenbanktransaktion, die über das Verbindungsobjekt gesteuert und verwaltet wird.
JTA-Transaktion: JTA bezieht sich auf die Java Transaction API (Java Transaction API), bei der es sich um die Java EE-Datenbanktransaktionsspezifikation handelt. stellt nur eine Transaktionsverwaltungsschnittstelle bereit . Die von der Anwendung gesteuerten Serveranbieter (z. B. WebSphere Application Server) sind leistungsfähiger als JDBC und unterstützen verteilte Transaktionen .
Je nachdem, ob Programmierung verwendet wird, wird sie in deklarative Transaktionen und programmatische Transaktionen unterteilt. Weitere Informationen finden Sie unter http://blog.csdn.net/liaohaojian/article/details /70139151
Deklarative Transaktionen: implementiert durch XML-Konfiguration oder Anmerkungen.
Programmatische Transaktionen: Implementieren Sie bei Bedarf Geschäftslogik durch Programmiercode mit geringerer Granularität.
ISOLATION_DEFAULT: Verwenden Sie die Standardisolationsstufe der zugrunde liegenden Datenbank, unabhängig davon, was der Datenbankadministrator festlegt
ISOLATION_READ_UNCOMMITTED (nicht festgeschriebener Lesevorgang) : Die niedrigste Isolationsstufe. Bevor die Transaktion festgeschrieben wird, kann sie von anderen Transaktionen gelesen werden (Phantom-Lesevorgänge, schmutzige Lesevorgänge und nicht wiederholbare Lesevorgänge treten auf).
ISOLATION_READ_COMMITTED (festgeschriebenes Lesen) : Eine Transaktion kann nur von anderen Transaktionen gelesen werden, nachdem sie übermittelt wurde (diese Isolationsstufe verhindert, dass andere Transaktionen die Daten von nicht festgeschriebenen Daten lesen). Transaktionen, daher wird es immer noch zu Phantom-Lesungen und nicht wiederholbarem Lesen kommen), SQL-Server-Standardebene
ISOLATION_REPEATABLE_READ (wiederholbares Lesen) : wiederholbares Lesen, um dasselbe sicherzustellen mehrfach lesen Wenn ein Datenelement generiert wird, stimmt sein Wert mit dem Inhalt zu Beginn der Transaktion überein und es ist verboten, nicht festgeschriebene Daten aus anderen Transaktionen zu lesen (diese Isolierung kann grundsätzlich schmutzige Lesevorgänge und nicht wiederholbare Lesevorgänge verhindern ( der Fokus liegt auf der Änderung), aber Phantom-Lesevorgänge werden stattfinden (Der Fokus liegt auf dem Hinzufügen und Löschen)) (MySql-Standardebene, Änderungen können durch Festlegen der Transaktionsisolationsebene vorgenommen werden )
ISOLATION_SERIALIZABLE (Serialisierung) : Die teuerste und zuverlässigste Isolationsstufe (diese Isolationsstufe kann schmutzige Lesevorgänge, nicht wiederholbare Lesevorgänge und Phantom-Lesevorgänge verhindern)
Verlorene Aktualisierung: Zwei Transaktionen aktualisieren gleichzeitig eine Datenzeile. Die Aktualisierung der letzten Transaktion überschreibt die Aktualisierung der ersten Transaktion, was zum Verlust der aktualisierten Daten führt durch die erste Transaktion. Dies wird durch keine Sperre verursacht.
Phantomlesung: Während derselben Transaktionsoperation werden dieselben Daten mehrmals (verschiedene Transaktionen) in unterschiedlichen Zeiträumen gelesen. und der gelesene Inhalt ist inkonsistent (im Allgemeinen wird die Anzahl der Zeilen mehr oder weniger).
Dirty Read: Eine Transaktion liest den Inhalt einer anderen Transaktion, die nicht erwähnt wird, was ein Dirty Read ist.
Nicht wiederholbares Lesen: In derselben Transaktion ist der mehrmals gelesene Inhalt inkonsistent (im Allgemeinen bleibt die Anzahl der Zeilen gleich, aber der Inhalt ändert sich).
Der Unterschied zwischen Phantomlesen und nicht wiederholbarem Lesen: Der Schwerpunkt des Phantomlesens liegt im Einfügen und Löschen, also der zweiten Abfrage Finden Sie mehr Informationen als die erste Die Abfragedaten werden kleiner oder größer, so dass den Menschen eine Illusion vermittelt wird. Der entscheidende Punkt des nicht wiederholbaren Lesens ist Änderung, das heißt, die zweite Abfrage findet die Abfrage Die Ergebnisse stimmen nicht mit den ersten Abfrageergebnissen überein, d. h. das erste Ergebnis ist nicht mehr reproduzierbar.
Je höher die Datenbankisolationsstufe, desto höher sind die Ausführungskosten und desto schlechter ist die Fähigkeit zur gleichzeitigen Ausführung. Daher müssen bei der Entwicklung und Verwendung tatsächlicher Projekte umfassende Überlegungen angestellt werden, um die Parallelitätsleistung Verwenden Sie im Allgemeinen , um die Leseisolationsstufe zu übermitteln, wodurch verlorene Aktualisierungen und fehlerhafte Lesevorgänge vermieden werden können. Obwohl nicht wiederholbare Lesevorgänge und Phantomlesevorgänge nicht vermieden werden können, können pessimistische Sperren oder optimistische Sperren auftreten werden verwendet, um diese Probleme nach Möglichkeit zu lösen.
PROPAGATION_REQUIRED: Unterstützt die aktuelle Transaktion. Wenn keine aktuelle Transaktion vorhanden ist, erstellen Sie eine neue.
PROPAGATION_SUPPORTS: unterstützt die aktuelle Transaktion. Wenn derzeit keine Transaktion vorhanden ist, wird sie nicht transaktional ausgeführt (im Quellcode gibt es einen Hinweis darauf). ist nicht klar, also belassen Sie es für später) wird später untersucht).
PROPAGATION_MANDATORY: Unterstützt die aktuelle Transaktion. Wenn keine aktuelle Transaktion vorhanden ist, wird eine Ausnahme ausgelöst (sie muss in einer vorhandenen Transaktion ausgeführt werden). Die Geschäftsmethoden können ihre eigenen Transaktionen nicht selbstständig initiieren.
PROPAGATION_REQUIRES_NEW: Erstellen Sie immer eine neue Transaktion. Wenn derzeit eine Transaktion vorliegt, wird die ursprüngliche Transaktion ausgesetzt.
PROPAGATION_NOT_SUPPORTED: Die aktuelle Transaktion wird nicht unterstützt und wird immer auf nicht-transaktionale Weise ausgeführt. Wenn die aktuelle Transaktion vorhanden ist, wird die Transaktion ausgesetzt .
PROPAGATION_NEVER: Die aktuelle Transaktion wird nicht unterstützt; wenn die aktuelle Transaktion vorhanden ist, wird eine Ausnahme ausgelöst.
PROPAGATION_NESTED: Wenn die aktuelle Transaktion vorhanden ist, führen Sie sie in einer verschachtelten Transaktion aus. Wenn keine aktuelle Transaktion vorhanden ist, führen Sie ähnliche Vorgänge wie PROPAGATION_REQUIRED aus (Hinweis: Bei Anwendung auf JDBC gilt dies nur für JDBC 3.0 oder höher.
1 Verschiedene Datenquellen. Es gibt drei allgemeine Kategorien
Die integrierten Transaktionsmanager erben alle die abstrakte Klasse AbstractPlatformTransactionManager, die wiederum die Schnittstelle PlatformTransactionManager erbtDer Kern der Transaktionsunterstützung des Spring-Frameworks Management ist der Transaktionsmanager Zusammenfassung: Für verschiedene Datenzugriffs-Frameworks wird die Strategieschnittstelle PlatformTransactionManager implementiert, um das Transaktionsmanagement mehrerer Datenzugriffs-Frameworks zu unterstützen. PlatformTransactionManager-Schnittstelle ist wie folgt definiert
DataSourceTransactionManager: unter dem Paket org.springframework.jdbc.datasource die Datenquellen-Transaktionsverwaltung Klasse, stellt Transaktionsverwaltung für eine einzelne javax.sql.DataSource-Datenquelle bereit, sofern sie für die Transaktionsverwaltung von JDBC und Mybatis-Framework verwendet wird.
HibernateTransactionManager: Unter dem Paket org.springframework.orm.hibernate3 bietet die Datenquellen-Transaktionsverwaltungsklasse Unterstützung für eine einzelne org.hibernate.SessionFactory-Transaktion zur Integration . Transaktionsverwaltung im Hibernate-Framework; Dieser Transaktionsmanager unterstützt nur die Hibernate3+-Version und die Spring3.0+-Version unterstützt nur die Hibernate 3.2+-Version
JtaTransactionManager: Befindet sich im Paket org.springframework.transaction.jta, bietet Unterstützung für die verteilte Transaktionsverwaltung und delegiert die Transaktionsverwaltung an den Java EE-Anwendungsserver oder passt sie nativ an JTA-Transaktionsmanager, eingebettet in die Anwendung.
Die TransactionStatus-Schnittstelle ist wie folgt definiert:
public interface TransactionStatus extends SavepointManager { boolean isNewTransaction(); //返回当前事务是否是新的事务 boolean hasSavepoint(); //返回当前事务是否有保存点 void setRollbackOnly(); //设置事务回滚 boolean isRollbackOnly(); //设置当前事务是否应该回滚 void flush(); //用于刷新底层会话中的修改到数据库,一般用于刷新如Hibernate/JPA的会话,可能对如JDBC类型的事务无任何影响; boolean isCompleted(); //返回事务是否完成 }2. Spring Distributed Transaction Configuration
bezieht sich auf die JNDI-Datenquelle des Anwendungsservers (z. B. Tomcat). ), um JTA-Transaktionen indirekt zu implementieren. Das Management verlässt sich auf den Anwendungsserver
, um JOTM (offizielle Website: http://jotm.objectweb.org/) und Atomikos (offizielle Website: https) direkt zu integrieren ://www.atomikos.com/ ) Bietet JTA-Transaktionsverwaltung (keine Anwendungsserverunterstützung, wird häufig für Unit-Tests verwendet)
Verwenden Sie einen anwendungsserverspezifischen Transaktionsmanager und nutzen Sie erweiterte Funktionen von JTA-Transaktionen (Weblogic, Websphere)
1). Referenzieren Sie die JNDI-Datenquelle des Anwendungsservers (z. B. Tomcat), um die JTA-Transaktionsverwaltung indirekt zu implementieren >
<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数据源 --> <jee:jndi-lookup id="dataSource" jndi-name="jdbc/test"/> <!-- JTA事务管理器 --> <bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <!--transactionManagerName指定JTA事务管理器的JNDI名字,从而将事务管理委托给该事务管理器 --> <property name="transactionManagerName" value="java:comp/TransactionManager"/> </bean> </beans>2) Verwenden Sie Atomikos, um die verteilte Transaktionsverwaltung zu implementieren. Die Konfiguration ist wie folgt:<?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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd" > <context:component-scan base-package="com.suicai.*.service.impl" /> <context:component-scan base-package="com.suicai.util" /> <!-- 此方法加载的配置文件仅仅在xml中使用,但是工具类都采用注解的方式 --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value="classpath:conn.properties" /> </bean> <!-- 仅仅支持注解不支持在xml配置中使用properties文件 在类中可以使用SPEL表达式来加载相应的值 --> <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.AtomikosDataSourceBean" init-method="init" destroy-method="close" abstract="true"> <property name="borrowConnectionTimeout" value="60"/> <!--获取连接失败重新获等待最大时间,在这个时间内如果有可用连接,将返回--> <property name="reapTimeout" value="20"/> <!--最大获取数据时间,如果不设置这个值,Atomikos使用默认的5分钟,那么在处理大批量数据读取的时候,一旦超过5分钟,就会抛出类似 Resultset is close 的错误.--> <property name="maintenanceInterval" value="60" /> <!--连接回收时间--> <property name="loginTimeout" value="60" /> <!--java数据库连接池,最大可等待获取datasouce的时间--> <property name="logWriter" value="60"/> <property name="minPoolSize" value="1" /> <!-- 连接池中保留的最小连接数 --> <property name="maxPoolSize" value="3" /> <!-- 连接池中保留的最大连接数 --> <property name="maxIdleTime" value="60" /> <!-- 最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 --> </bean> <!-- 配置2个数据源 mysql --> <bean id="ds_suicai" parent="abstractXADataSource"> <!-- uniqueResourceName表示唯一资源名,如有多个数据源不可重复; --> <property name="uniqueResourceName" value="suicaifortest" /> <!-- xaDataSourceClassName是具体分布式数据源厂商实现; --> <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/> <!-- xaProperties属性指定具体厂商数据库属性 --> <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表示唯一资源名,如有多个数据源不可重复; --> <property name="uniqueResourceName" value="puildingpurchasefortest" /> <!-- xaDataSourceClassName是具体分布式数据源厂商实现; --> <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/> <!-- xaProperties属性指定具体厂商数据库属性 --> <property name="xaProperties"> <props> <prop key="URL">${db.jdbcUrlTwo}</prop> <prop key="user">${user}</prop> <prop key="password">${password}</prop> </props> </property> </bean> <!-- 动态配置数据源 --> <bean id="dataSource2" 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 ="sqlSessionFactoryBeanA" class="org.mybatis.spring.SqlSessionFactoryBean" > <!-- 指定数据源 --> <property name ="dataSource" ref="ds_suicai" /> <!-- 指定mybatis 的配置文件 --> <property name ="configLocation" value="classpath:mybatis.cfg.xml" /> </bean> <bean id ="sqlSessionFactoryBeanB" class="org.mybatis.spring.SqlSessionFactoryBean" > <!-- 指定数据源 --> <property name ="dataSource" ref="ds_kaizhi" /> <!-- 指定mybatis 的配置文件 --> <property name ="configLocation" value="classpath:mybatis.cfg.xml" /> </bean> <!--CustomSqlSessionTemplate继承SqlSessionTemplate重写getSqlSessionFactory方法,具体请下载查看--> <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_kaizhi1"></entry > </map> </property> </bean> <!-- 配置atomikos事务管理器 --> <bean id="atomikosTransactionManager" class = "com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method = "close"> <property name="forceShutdown" value="true"/> </bean> <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"></bean> <!-- 配置spring事务管理器 --> <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="transactionManager"> <ref bean="atomikosTransactionManager"/> </property> <property name="userTransaction"> <ref bean="atomikosUserTransaction"/> </property> <!-- 必须设置,否则程序出现异常 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:必须要有事务, 如果没有就在上下文创建一个 --> <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"/> <!-- 支持,如果有就有,没有就没有 --> <tx:method name="*" propagation="SUPPORTS"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut expression="execution(* com.suicai.*.service.impl.*.*(..))" id="pointcut"/> <!-- 吧 tx与aop的配置关联,才是完整的声明事务配置 --> <aop:advisor advice-ref="advice" pointcut-ref="pointcut"/> </aop:config> <!-- 采用包扫描机制,自动会把指定的包里面的所有dao注册 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 注意注入sqlSessionTemplate --> <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存放的目录--> <property name="prefix"> <value>/</value> </property> <!--jsp文件的后缀--> <property name="suffix"> <value>.jsp</value> </property> </bean> <!-- 验证码 --> <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>
Das obige ist der detaillierte Inhalt vonDie Isolationsstufe der Spring-Transaktion, das Ausbreitungsverhalten und Spring+mybatis+atomikos realisieren eine verteilte Transaktionsverwaltung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!