<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 来实现,主要是统一封装非功能性需求。
事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。
特点:事务是恢复和并发控制的基本单位。
事务应该具有 4 个属性:原子性、一致性、 隔离性、持久性。这四个属性通常称为 ACID 特性。
原子性(Automicity):一个事务是一个不可分割的工作单位,事务中包括的诸操作要 么都做,要么都不做。
一致性(Consistency):事务必须是使数据库从一个一致性状态变到另一个一致性状态。 一致性与原子性是密切相关的。
隔离性(Isolation):一个事务的执行不能被其他事务干扰。即一个事务内部的操作及 使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
持久性(Durability):持久性也称永久性(Permanence),指一个事务一旦提交,它 对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何 影响。
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 实现的。
脏读:一事务对数据进行了增删改,但未提交,另一事务可以读取到未提交的数据。如 果第一个事务这时候回滚了,那么第二个事务就读到了脏数据。
不可重复读:一个事务中发生了两次读操作,第一次读操作和第二次操作之间,另外一 个事务对数据进行了修改,这时候两次读取的数据是不一致的。
幻读:第一个事务对一定范围的数据进行批量修改,第二个事务在这个范围增加一条数 据,这时候第一个事务就会丢失对新增数据的修改。
总结:
隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。 大多数的数据库默认隔离级别为 Read Commited,比如 SqlServer、Oracle 少数数据库默认隔离级别为:Repeatable Read 比如: MySQL InnoDB
Consistency 一致性
Availability 可用性
Partition Tolearace 分区容错性
DTS:通过日志还原,显然滞后,变成异步操作
强一致性:当更新操作完成之后,任何多个后续进程或者线程的访问都会返回最新的更 新过的值。这种是对用户最友好的,就是用户上一次写什么,下一次就保证能读到什么。 根据 CAP 理论,这种实现需要牺牲可用性。
弱一致性:系统并不保证后续进程或者线程的访问都会返回最新的更新过的值。系统在 数据写入成功之后,不承诺立即可以读到最新写入的值,也不会具体的承诺多久之后可 以读到。
最终一致性:弱一致性的特定形式。系统保证在没有后续更新的前提下,系统最终返回 上一次更新操作的值。在没有故障发生的前提下,不一致窗口的时间主要受通信延迟, 系统负载和复制副本的个数影响。DNS 是一个典型的最终一致性系统。
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 配置文件中自定义的命名空间。