一, 事务的 ACID 特性 : 原子性, 一致性, 隔离性, 持久性
二, 事务的分内
事物分为两种, 一种是编程式事务, 就是之前利用 JDBC 写的 commit 和 rowback 的方式提交或者回滚事物, 这种控制事物的方式比较麻烦, 一般在做大型项目的时候不建议使用这种方式.
另一种是声明式事务, 就像字面上的意思一样, 在一个地方声明一下, 然后程序中不需要再由事物控制的代码, 使用简单.
三, spring 支持声明式事物, 配置如下:
dao 层, 持久化层 (负责连接数据库, 执行数据库的)
service 层 业务逻辑层 (负责实现系统所有的业务逻辑)
controller 层 控制层 (接收前台参数, 调用 service 层业务逻辑, 往前台返回数据)
保存订单的业务实现:
控制层: 负责接收前台传过来的订单信息, 订单明细的信息 , 调用业务逻辑层保存订单的方法
业务逻辑层: 写保存订单的方法 保存订单的方法应该先调持久化层保存主订单的方法, 再调用持久层保存订单明 细的方法
持久化层: 保存主订单的方法 保存订单明细的方法
我们不希望出现保存订单的时候 主订单保存成功之后, 出现了异常, 然后订单明细没有保存成功, 如果是这样, 数 据库中的数据就不完整的了. 所以我们一般为了避免这种类似的情况, 我们可以把事物加到 service 层.
spring 配置文件: applicationContext.xml
- <?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:context="http://www.springframework.org/schema/context"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/springcontext.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/springaop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
- <!-- 扫描 dao 接口所在的包 -->
- <context:component-scan base-package="com.aaa.spring.dao.impl,com.aaa.spring.service.impl">
- </context:component-scan>
- <!--- 创建 dbcp 数据源连接池对象 -->
- <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
- <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
- <property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"></property>
- <property name="username" value="scott"></property>
- <property name="password" value="tiger"></property>
- </bean>
- <!-- 创建 jdbcTemplate 对象 -->
- <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
- <property name="dataSource" ref="dataSource"></property>
- </bean>
- <!--- 创建 spring 的事物管理器对象 -->
- <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
- <property name="dataSource" ref="dataSource"></property></bean>
- <!--- 创建 spring 事物管理的通知类对象 -->
- <tx:advice id="txAdvice" transaction-manager="transactionManager">
- <!--- 此处可以配置事物管理的一些特性 -->
- <tx:attributes>
- <!---
- name 属性中可以使用通配符, 用来指定该属性对哪些方法起作用
- propagation 配置事物的传播特性
- REQUIRED 判断当前方法是否存在事物, 如果不存在事物就创建一个新的事物, 如果存在事物就使用当前的事
- 物
- REQUIRES_NEW 判断当前方法是否存在事物 , 如果不存在事物就创建一个新的事物,
- 如果存在事物, 就把当前事物挂起, 再启动一个新的事物
- NESTED 嵌套事物 . 判断当前方法是否存在事物, 如果不存在事物就创建一个事物, 如果存在事物, 把当前事物
- 挂起,
- 再启动一个当前事物的子事物 . 这样如果父事物产生了异常. 子事物即使没有产生异常也会回滚.
- read-only 配置事物的只读特性
- true 当前事物是只读事物, 在方法之后不会提交事物
- flase 默认值 当前事物是非只读事物, 在方法之后会提交事物
- 配置事物的只读特性 增删改方法一般需要事物, 查询方法一般不需要事物, 所以以后开发的时候最好查询方法把
- read-only
- 设置成 true, 在一定程度上能提高程序的运行效率
- -->
- <tx:method name="save*" propagation="NESTED" />
- <tx:method name="select*" propagation="REQUIRED" read-only="true"></tx:method>
- </tx:attributes>
- </tx:advice>
- <!--- 配置 spring 的声明式事物 -->
- <aop:config>
- <!--- 声明切入点对象 告诉 spring 要对哪些类的哪些方法使用事物 -->
- <aop:pointcut id="p1" expression="execution(* com.aaa.spring.service.impl.*.*(..))"></aop:pointcut>
- <!-- 声明事物管理专用的切面 -->
- <aop:advisor advice-ref="txAdvice" pointcut-ref="p1"></aop:advisor>
- </aop:config>
- </beans>
事物什么时候回滚? service 方法如果抛出运行异常, 才会回滚.
注解配置:
- <?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:context="http://www.springframework.org/schema/context"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
- <context:component-scan base-package="com.aaa.spring"></context:component-scan>
- <!-- 创建 dbsp 数据源连接池对象 -->
- <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
- <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
- <property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"></property>
- <property name="username" value="scott"></property>
- <property name="password" value="tiger"></property>
- </bean>
- <!-- 创建 jdbcTemplate 对象 -->
- <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
- <property name="dataSource" ref="dataSource"></property>
- </bean>
- <!-- 创建 spring 的事物管理器对象 -->
- <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
- <property name="dataSource" ref="dataSource"></property>
- </bean>
- <!-- 声明以注解的方式配置声明式事物 -->
- <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
- </beans>
第二步, 要在需要使用事物的类上增加 @Transactional 注解
面试题:
你知道那些数据源连接池?
dbcp,c3p0, 阿里巴巴 druid ,BoneCP,Proxool,DBPoll, Primrose 等.
事物分几种方式
编程式事物, spring 支持声明式事物.
spring 事物处理的机制, 底层采用的是 AOP 的机制
来源: http://www.bubuko.com/infodetail-3070675.html