Spring 事务详解
来源:互联网 发布:华为mate9网络频段 编辑:程序博客网 时间:2024/06/11 08:29
1 事务的回顾
(1) 什么是事务:
事务逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败
(2) 事务特性:
原子性:强调事务的不可分割.
一致性:事务的执行的前后数据的完整性保持一致.
隔离性:一个事务执行的过程中,不应该受其他事务的干扰.
持久性:事务一旦结束,数据就持久到数据库
(3) 如果不考虑隔离性引发安全性问题:
脏读:一个事务读到另一个事务的未提交的数据
不可重复读:一个事务读到另一个事务已经提交的update的数据导致多次查询结果不一致.
虚幻读:一个事务读到另一个事务已经提交的insert的数据导致多次查询结果不一致.
(4) 解决读问题:设置事务隔离级别
未提交读:脏读,不可重复读,虚读都有可能发生
已提交读:避免脏读。但是不可重复读和虚读有可能发生
可重复读:避免脏读和不可重复读.但是虚读有可能发生.
串行化的:避免以上所有读问题.
(5) MySQL默认:可重复读
Oracle默认:读已提交
2 Spring 进行事物管理一组API
Spring 进行事物管理主要分为编程式事务和声明式事务
(1) 编程式事务:编程式事务需要你在代码中直接加入处理事务的逻辑,可能需要在代码中显式调用beginTransaction()、commit()、rollback()等事务管理相关的方法,如在执行a方法时候需要事务处理,你需要在a方法开始时候开启事务,处理完后。在方法结束时候,关闭事务.在实际项目开发当中一般不使用。
(2) 声明式事务:声明式的事务的做法是在a方法外围添加注解或者直接在配置文件中定义,a方法需要事务处理,在spring中会通过配置文件在a方法前后拦截,并添加事务.
① 基于注解方式的声明式事务
② 基于XML方式的声明式事务
3 基于注解方式的声明式事务
(1) 增加相关配置:增加tx名称空间
<?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/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 扫描注解的包 --> <context:component-scan base-package="com.atguigu.spring.*"/> <!-- 加载外部资源文件 --> <context:property-placeholder location="classpath:jdbc.properties"/> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="user" value="${jdbc.user}"/> <property name="password" value="${jdbc.password}"/> <property name="jdbcUrl" value="${jdbc.jdbcUrl}"/> <property name="driverClass" value="${jdbc.driverClass}"/> <property name="initialPoolSize" value="${jdbc.initialPoolSize}"/> <property name="minPoolSize" value="${jdbc.minPoolSize}"/> <property name="maxPoolSize" value="${jdbc.maxPoolSize}"/> <property name="acquireIncrement" value="${jdbc.acquireIncrement}"/> <property name="maxStatements" value="${jdbc.maxStatements}"/> <property name="maxStatementsPerConnection" value="${jdbc.maxStatementsPerConnection}"/> </bean> <!-- 声明JdbcTemplate --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 事务管理器:用于完成事务的开启,提交,回滚 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 开启基于注解的声明式事务 transaction-manager="transactionManager" 默认值。 --> <tx:annotation-driven transaction-manager="transactionManager"/></beans>
(2) 在业务层方法上使用事务注解增加事务
@Service("bookShopService")public class BookShopServiceImpl implements BookShopService { @Autowired private BookShopDao bookShopDao ; //1.测试没有事务情况(正常运行) //2.测试没有事务情况(非正常运行:数据操作失败,有的语句执行成功了,有的语句失败,没有保证数据一致性和完整性。) //3.测试有事务情况 :@Transactional @Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.REPEATABLE_READ, rollbackFor={java.lang.Exception.class}, timeout=3,readOnly=true) public void purchase(String isbn, String username) throws Exception { int price = bookShopDao.findBookPriceByIsbn("ISBN-001"); int price2 = bookShopDao.findBookPriceByIsbn("ISBN-001"); } @Transactional(propagation=Propagation.REQUIRED) public void updatePrice(String isbn, int price) throws Exception { bookShopDao.updateBookPrice(isbn,price); }}
propagation:事务的传播行为;
isolation:事务的隔离级别设置;
rollbackFor:事务的异常处理;
timeout:事务的超时属性;
readOnly:事务的只读属性设置;
(3) 框架如何创建代理对象,实现事务的功能扩展
目标对象有接口采用JDK动态代理, 如果目标对象没有接口,会采用Cglib动态代理。
(4) 事务的属性
① 事务的传播行为propagation :a() -> b():a()方法调用b()方法,b()方法的事务传播行为:
REQUIRED :
如果a()方法没有事务,那么,b()方法要开启一个新的事务
如果a()方法有事务,那么,b()方法要加入a()方法事务中。
REQUIRES_NEW:
如果a()方法没有事务,那么,b()方法要开启一个新的事务。
如果a()方法有事务,那么b()方法也要为自己开启一个新的事务,当b()方法运行时,a()方法事务要挂起,直到b()方法事务结束后,a()方法事务继续执行。
②事务的隔离级别 isolation: 1,2,4,8 数据库定义的隔离级别。
③事务的回滚策略
Spring框架遇到异常时,并不是所有的异常都进行事务回滚。
如果遇到Exception或Error不会进行事务自动回滚;如果是RuntimeException异常,默认进行回滚。
如果希望存在异常就进行回滚,那么可以修改异常回滚策略:
rollbackFor={java.lang.Exception.class} 指定哪些异常类型需要回滚事务noRollbackFor={} 指定哪些异常类型不需要回滚。方法中如果自己处理了异常,为了让事务得到回滚,必须要将异常抛给框架。否则,不会进行事务回滚。
④事务的超时属性
如果事务执行过程中,超出一定的时间,需要将事务结束掉,可以设置超时属性值。
目的,事务执行时间过长,会对其他事务操作数据有影响。系统性能降低。
⑤事务的只读属性
如果是做数据查询操作,而不是数据的修改(insert,update,delete),可以不进行事务控制。
为了提高数据的访问效率,可以设置只读操作。让数据库对只读操作进行性能的优化,提高数据的访问效率。
4 基于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/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 加载外部资源文件 --> <context:property-placeholder location="classpath:jdbc.properties"/> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="user" value="${jdbc.user}"/> <property name="password" value="${jdbc.password}"/> <property name="jdbcUrl" value="${jdbc.jdbcUrl}"/> <property name="driverClass" value="${jdbc.driverClass}"/> <property name="initialPoolSize" value="${jdbc.initialPoolSize}"/> <property name="minPoolSize" value="${jdbc.minPoolSize}"/> <property name="maxPoolSize" value="${jdbc.maxPoolSize}"/> <property name="acquireIncrement" value="${jdbc.acquireIncrement}"/> <property name="maxStatements" value="${jdbc.maxStatements}"/> <property name="maxStatementsPerConnection" value="${jdbc.maxStatementsPerConnection}"/> </bean> <!-- 声明JdbcTemplate --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 事务管理器:用于完成事务的开启,提交,回滚 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <bean id="bookShopDao" class="com.atguigu.spring.dao.BookShopDaoImpl"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean> <!-- 目标对象 --> <bean id="bookShopService" class="com.atguigu.spring.service.BookShopServiceImpl"> <property name="bookShopDao" ref="bookShopDao"></property> </bean> <!-- 事务与业务层对象之间的关系 --> <aop:config> <!-- 声明切入点 --> <aop:pointcut expression="execution(* com.atguigu..service.*.*(..))" id="pointcutID"/> <!-- 声明切入点与通知之间的关系 --> <aop:advisor advice-ref="txAdviceID" pointcut-ref="pointcutID"/> </aop:config> <!-- 声明通知 --> <tx:advice id="txAdviceID" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="purchase" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception" timeout="3"/> <tx:method name="update*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception" timeout="3"/> <tx:method name="add*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception" timeout="3"/> <tx:method name="delete*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception" timeout="3"/> <tx:method name="query*" read-only="true"/> <tx:method name="get*" read-only="true"/> </tx:attributes> </tx:advice></beans>
阅读全文
1 0
- Spring详解-----------事务详解
- Spring详解-----------事务详解
- 详解spring事务属性
- 详解spring事务属性
- 详解spring事务属性
- 详解spring事务属性
- 详解spring事务属性
- 详解spring事务属性
- 详解spring事务属性
- 详解spring事务属性
- 详解spring事务属性
- 详解spring事务属性
- spring事务详解
- 详解spring事务属性
- spring 嵌套事务 详解
- 详解spring事务属性
- 详解spring事务属性
- spring事务属性详解
- 1002. A+B for Polynomials (25)
- openjudge 6256 带通配符的字符串匹配(动态规划)
- Linux网络编程——I/O多路复用
- 17.8.27 校内赛 解题报告【卢卡斯定理】【dfs+hash】【线段树】
- 小白文科生眼中的Linux系统
- Spring 事务详解
- 51Nod 迷宫游戏
- 匈牙利模板--poj 3041最小匹配
- 【asp.net】小结
- Go 语言,开源服务端代码自动生成 框架
- Anaconda使用总结
- This software comes from a 3rd party and may contain non-free components的解决方法
- 无符号整数的bitmap
- 杂记