Skip to content

Latest commit

 

History

History
130 lines (80 loc) · 8.45 KB

08.Spring事务传播原理及数据库事务操作原理.md

File metadata and controls

130 lines (80 loc) · 8.45 KB

Spring事务传播原理

Spring事务的配置原理

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
						http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
						http://www.springframework.org/schema/tx 
						http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
						http://www.springframework.org/schema/aop 
						http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
	<aop:aspectj-autoproxy proxy-target-class="true"/>
	
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"/>
	</bean>

	<!-- 配置事务通知属性 -->
	<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="add*" propagation="REQUIRED" rollback-for="Exception,RuntimeException,SQLException"/>
			<tx:method name="remove*" propagation="REQUIRED" rollback-for="Exception,RuntimeException,SQLException"/>
			<tx:method name="edit*" propagation="REQUIRED" rollback-for="Exception,RuntimeException,SQLException"/>
			<tx:method name="login" propagation="NOT_SUPPORTED"/>
			<tx:method name="query*" read-only="true"/>
		</tx:attributes>
	</tx:advice>

	<aop:config>
		<aop:advisor advice-ref="transactionAdvice" pointcut-ref="transactionPointcut"/>
        <aop:aspect ref="dataSource">
            <aop:pointcut id="transactionPointcut" expression="execution(public * com.gupaoedu..*.service..*Service.*(..))" />
        </aop:aspect>
    </aop:config>
	
</beans>

Spring 事务管理基于 AOP 来实现,主要是统一封装非功能性需求。

数据库事务原理详解

1、事务基本概念

事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。

特点:事务是恢复和并发控制的基本单位。

事务应该具有 4 个属性:原子性、一致性、 隔离性、持久性。这四个属性通常称为 ACID 特性。

原子性(Automicity):一个事务是一个不可分割的工作单位,事务中包括的诸操作要 么都做,要么都不做。

一致性(Consistency):事务必须是使数据库从一个一致性状态变到另一个一致性状态。 一致性与原子性是密切相关的。

隔离性(Isolation):一个事务的执行不能被其他事务干扰。即一个事务内部的操作及 使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

持久性(Durability):持久性也称永久性(Permanence),指一个事务一旦提交,它 对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何 影响。

2、事务的基本原理

1、获取连接 Connection con = DriverManager.getConnection()

2、开启事务 con.setAutoCommit(true/false);

3、执行 CRUD

4、提交事务/回滚事务 con.commit() / con.rollback(); 5、关闭连接 conn.close();

使用 Spring 的事务管理功能后,我们可以不再写步骤 2 和 4 的代码,而是由 Spirng 自 动完成。 那么 Spring 是如何在我们书写的 CRUD 之前和之后开启事务和关闭事务的 呢?解决这个问题,也就可以从整体上理解 Spring 的事务管理实现原理了。下面简单地 介绍下,注解方式为例子 配置文件开启注解驱动,在相关的类和方法上通过注解@Transactional 标识。 Spring 在启动的时候会去解析生成相关的 bean,这时候会查看拥有相关注解的类和方 法,并且为这些类和方法生成代理,并根据@Transaction 的相关参数进行相关配置注入, 这样就在代理中为我们把相关的事务处理掉了(开启正常提交事务,异常回滚事务)。 真正的数据库层的事务提交和回滚是通过 binlog 或者 redo log 实现的。

3、事务传播属性

image-20220222004721296

4、数据库事务的隔离级别

image-20220222005533003

脏读:一事务对数据进行了增删改,但未提交,另一事务可以读取到未提交的数据。如 果第一个事务这时候回滚了,那么第二个事务就读到了脏数据。

不可重复读:一个事务中发生了两次读操作,第一次读操作和第二次操作之间,另外一 个事务对数据进行了修改,这时候两次读取的数据是不一致的。

幻读:第一个事务对一定范围的数据进行批量修改,第二个事务在这个范围增加一条数 据,这时候第一个事务就会丢失对新增数据的修改。

总结:

隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。 大多数的数据库默认隔离级别为 Read Commited,比如 SqlServer、Oracle 少数数据库默认隔离级别为:Repeatable Read 比如: MySQL InnoDB

5、Spring 中的隔离级别

image-20220222010235992

6、CAP

Consistency 一致性

Availability 可用性

Partition Tolearace 分区容错性

DTS:通过日志还原,显然滞后,变成异步操作

强一致性:当更新操作完成之后,任何多个后续进程或者线程的访问都会返回最新的更 新过的值。这种是对用户最友好的,就是用户上一次写什么,下一次就保证能读到什么。 根据 CAP 理论,这种实现需要牺牲可用性。

弱一致性:系统并不保证后续进程或者线程的访问都会返回最新的更新过的值。系统在 数据写入成功之后,不承诺立即可以读到最新写入的值,也不会具体的承诺多久之后可 以读到。

最终一致性:弱一致性的特定形式。系统保证在没有后续更新的前提下,系统最终返回 上一次更新操作的值。在没有故障发生的前提下,不一致窗口的时间主要受通信延迟, 系统负载和复制副本的个数影响。DNS 是一个典型的最终一致性系统。

7、Spring事务API架构图

image-20220222220020924

7.1 异常处理

image-20220222220142297

SQLExceptionTranslator 是 一 个 接 口 , 如 果 你 需 要 在 SQLException 和 org.springframework.dao.DataAccessException 之间作转换,那么必须实现该接口。 转换器类的实现可以采用一般通用的做法(比如使用 JDBC 的 SQLState code),如果为了 使转换更准确,也可以进行定制(比如使用 Oracle 的 error code)。

SQLErrorCodeSQLExceptionTranslator 是 SQLExceptionTranslator 的默认实现。 该 实现使用指定数据库厂商的 error code,比采用 SQLState 更精确。转换过程基于一个 JavaBean ( 类 型 为 SQLErrorCodes ) 中 的 error code 。 这 个 JavaBean 由 SQLErrorCodesFactory 工厂类创建,其中的内容来自于 “sql-error-codes.xml”配置文 件 。 该 文 件 中 的 数 据 库 厂 商 代 码 基 于 Database MetaData 信 息 中 的 DatabaseProductName,从而配合当前数据库的使用。

SQLErrorCodeSQLExceptionTranslator 使用以下的匹配规则: 首 先 检 查 是 否 存 在 完 成 定 制 转 换 的子 类 实 现 。 通 常 SQLErrorCodeSQLExceptionTranslator 这个类可以作为一个具体类使用,不需要进行定制,那么这个规则将不适用。

接着将 SQLException 的 error code 与错误代码集中的 error code 进行匹配。 默认情 况下错误代码集将从 SQLErrorCodesFactory 取得。 错误代码集来自 classpath 下的 sql-error-codes.xml 文件,它们将与数据库 metadata 信息中的 database name 进行 映射。

使用 fallback 翻译器。SQLStateSQLExceptionTranslator 类是缺省的 fallback 翻译器。 config 模块 NamespaceHandler 接口,DefaultBeanDefinitionDocumentReader 使用该接口来处 理在 spring xml 配置文件中自定义的命名空间。

image-20220222220700912