请描述一下Spring的事务管理
1、声明式事务管理的定义:用在 Spring 配置文件中声明式的处理事务来代替代码式的处理事务。这样的好处是,事务管理不侵入开发的组件,具体来说,业务逻辑对象就不会意识到正在事务管理之中,事实上也应该如此,因为事务管理是属于系统层面的服务,而不是业务逻辑的一部分,如果想要改变事务管理策划的话,也只需要在定义文件中重新配置即可,这样维护起来极其方便。
基于 TransactionInterceptor 的声明式事务管理:两个次要的属性: transactionManager,用来指定一个事务治理器, 并将具体事务相关的操作请托给它; 其他一个是 Properties 类型的transactionAttributes 属性,该属性的每一个键值对中,键指定的是方法名,方法名可以行使通配符, 而值就是表现呼应方法的所运用的事务属性。
2、基于 @Transactional 的声明式事务管理:Spring 2.x 还引入了基于 Annotation 的体式格式,具体次要触及@Transactional 标注。@Transactional 可以浸染于接口、接口方法、类和类方法上。算作用于类上时,该类的一切public 方法将都具有该类型的事务属性。
编程式事物管理的定义:在代码中显式挪用 beginTransaction()、commit()、rollback()等事务治理相关的方法, 这就是编程式事务管理。Spring 对事物的编程式管理有基于底层 API 的编程式管理和基于 TransactionTemplate 的编程式事务管理两种方式。
(一)操作
1.xml声明式事务的操作案例
这里有案例和表,可以点进去参考
bean.xml
配置步骤
第一步:导入tx约束和名称空间(事务是基于aop的,aop的也得导入)
第二步:配置事务管理器(Spring框架的)DataSourceTransactionManager(需要在里面注入DataSource)
第三步:配置事务的通知(事务通知就表明让spring来处理何时提交和回滚)
3.1配置 transaction-manager=”transactionManager
3.2配置事务属性(传播途径,是否只读事务)
第四步:配置aop的切入点表达式,并建立和通知的关联
第五步:配置事务的属性
在事务通知的内部
配置事务管理器
需要添加依赖切面类依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.13</version>
</dependency>
用Spring框架的DataSourceTransactionManager
<bean id=”transactionManager” class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”>
<property name=”dataSource” ref=”dataSource”/>
</bean>
<tx:advice id=”txAdvice” transaction-manager=”transactionManager”>
<!—配置事务的属性用
代表匹配全部的方法(匹配全部级别比上面低,会先执行上面标签范围匹配方法)
read-only:是否只读事务。默认值是:”false”,表示读写。只有查询方法才能设置为true。
isolation:指定事务的隔离级别。默认值:”DEFAULT”,表示使用数据库的默认隔离级别。
timeout:指定超时时间。默认值是:”-1”,表示永不超时。如果设置了以秒为单位。
propagation:指定事务的传播行为。默认值是:”REQUIRED”,表示必须有事务,增删改方法的配置。查询方法使用SUPPORTS
rollback-for:用于指定一个异常,当产生该异常时,事务回滚,产生其他异常事务不再回滚。没有默认值,即遇到任何异常都回滚。
no-rollback-for:用于指定一个异常,当产生该异常时,事务不回滚,产生其他异常时,事务回滚。没有默认值,即遇到任何异常都回滚。
—>
<tx:attributes>
<tx:method name=”query*” read-only=”true” propagation=”SUPPORTS”/>
<tx:method name=”find*” read-only=”true” propagation=”SUPPORTS”/>
<tx:method name=”select*” read-only=”true” propagation=”SUPPORTS”/>
<tx:method name=”*” read-only=”false” propagation=”REQUIRED”/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id=”pt1” expression=”execution( com.itXML9.service..*(..))”></aop:pointcut>
<!-- 用aop:advisor标签建立切入点表达式和事务通知的关联<br /> advice-ref 引入事务通知<br /> pointcut-ref 引入切入点表达式 --><br /> <**aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"**></**aop:advisor**><br /> </**aop:config**><br />service层<br />@Service<br />**public class **AccountServiceImpl **implements **IAccountService {<br /> @Autowired **private **IAccountDao **iAccountDao**;
public int transactionAccount(String sourceName, String targetName, Float money)
throws Exception {
// 查询姓名
Account source = this.iAccountDao.queryAccountByName(sourceName);
Account target = this.iAccountDao.queryAccountByName(targetName);
// 加钱减钱操作
source.setMoney(source.getMoney() - money);
target.setMoney(target.getMoney() + money);
// 更新账户
this.iAccountDao.updateAccountByName(source);
int a = 1/0;
int flag = this.iAccountDao.updateAccountByName(target);
**return **flag;<br /> }<br />}<br /> <br />
2.关于事务的基本概念
Spring的事务 我们重点使用的是xml配置的方式.(也可以在环绕通知使用,但是不如xml配置方式)
spring的事务管理:是通过spring的AOP实现的
* 事务管理器(切面类)
PlatformTransactionManager : 接口
事务管理器的实现类
DataSourceTransactionManager:仅对dbc操作数据库有效
HibernateTransactionManager :对hibernate操作有效
JpaTransactionManager :对jpa操作有效
3.事务的传播行为
方法间的嵌套调用的时候,对事务的支持情况,需要掌握这儿两个
1、PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。
2、PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。
增删改:使用传播行为是:REQUIRED
需要事务,原因:因为增删改需要对数据库进行更改,如果过程中异常需要回滚
是否只读 :false
查询:使用传播行为是:SUPPORTS
不需要事务,原因:因为查询不需要对数据库进行更改,不需要进行事务
是否只读:true
4.关于声明式事务和编程式事务
声明式事务管理的定义:
用在 Spring 配置文件中声明式的处理事务来代替代码式的处理事务。
这样的好处是:事务管理不侵入开发的组件.
具体来说,业务逻辑对象就不会意识到正在事务管理之中,事实上也应该如此,因为事务管理是属于系统层面的服务,而不是业务逻辑的一部分,如果想要改变事务管理策划的话,也只需要在定义文件中重新配置即可,这样维护起来极其方便。
基于 TransactionInterceptor 的声明式事务管理:两个次要的属性: transactionManager,用来指 定 一 个 事务治理器 , 并 将 具 体 事 务 相 关 的 操 作 请 托 给 它 ; 其 他 一 个 是 Properties 类型的 transactionAttributes 属性,该属性的每一个键值对中,键指定的是方法名,方法名可以行使通配符, 而值就是表现呼应方法的所运用的事务属性。
编程式事务管理的定义:
在代码中显式挪用 beginTransaction()、commit()、rollback()等事务治理相关的方法,这就是编程式事务管理。 Spring 对事物的编程式管理有基于底层 API 的编程式管理和基于TransactionTemplate 的编程式事务管理两种方式。
基 于 底 层 API 的 编 程 式 管 理 : 凭 证 PlatformTransactionManager 、 TransactionDefinition 和TransactionStatus 三个焦点接口,来实现编程式事务管理。
基于 TransactionTemplate 的编程式事务管理:为了不损坏代码原有的条理性,避免出现每一个方法中都包括相同的启动事物、提交、回滚事物样板代码的现象,spring 提供了 transactionTemplate 模板来实现 编程式事务管理。
编程式事务与声明式事务这两者的区别:
编程式事务是自己写事务处理的类,然后调用
声明式事务是在配置文件中配置,一般搭配在框架里面使用!
5.如果事务没有作用看这里
SpringMVC扫描包的时候只扫描Controller层, 不要扫多了,如果SpringMVC容器扫多了,那么父子容器都有一套Service ,Controller肯定会用自己的Service容器, 结果就是父容器中配置的事务就不生效了.
http://www.cnblogs.com/hafiz/p/5875770.html
6.注解方式开启事务
1. 在配置文件开启对 事务注解的支持
2. 在需要事务的方法或者类上面添加注解
@Transactional
(二)事务失效的几种原因
参考
https://www.yuque.com/docs/share/536b2b1d-54f3-44e6-8afc-6325099ced39?#
https://www.yuque.com/docs/share/175b3293-acd5-460b-b0c3-84f51fd1cae3?#
(三)@Transactional
1.rollbackFor 详细介绍
什么情况回滚,什么情况不回滚问题
https://www.yuque.com/docs/share/551efd5b-da93-4f9b-a03f-59289badc9d0?#
(四)其它属性
propagation属性
propagation 代表事务的传播行为,默认值为 Propagation.REQUIRED,其他的属性信息如下:
· Propagation.REQUIRED:如果当前存在事务,则加入该事务,如果当前不存在事务,则创建一个新的事务。( 也就是说如果A方法和B方法都添加了注解,在默认传播模式下,A方法内部调用B方法,会把两个方法的事务合并为一个事务 )
· Propagation.SUPPORTS:如果当前存在事务,则加入该事务;如果当前不存在事务,则以非事务的方式继续运行。
· Propagation.MANDATORY:如果当前存在事务,则加入该事务;如果当前不存在事务,则抛出异常。
· Propagation.REQUIRES_NEW:重新创建一个新的事务,如果当前存在事务,暂停当前的事务。( 当类A中的 a 方法用默认Propagation.REQUIRED模式,类B中的 b方法加上采用 Propagation.REQUIRES_NEW模式,然后在 a 方法中调用 b方法操作数据库,然而 a方法抛出异常后,b方法并没有进行回滚,因为Propagation.REQUIRES_NEW会暂停 a方法的事务 )
· Propagation.NOT_SUPPORTED:以非事务的方式运行,如果当前存在事务,暂停当前的事务。
· Propagation.NEVER:以非事务的方式运行,如果当前存在事务,则抛出异常。
· Propagation.NESTED :和 Propagation.REQUIRED 效果一样。
isolation 属性
isolation :事务的隔离级别,默认值为 Isolation.DEFAULT。
TransactionDefinition.ISOLATION_DEFAULT: 使用后端数据库默认的隔离级别,Mysql 默认采用的 REPEATABLE_READ隔离级别 Oracle 默认采用的 READ_COMMITTED隔离级别.
TransactionDefinition.ISOLATION_READ_UNCOMMITTED: 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
TransactionDefinition.ISOLATION_READ_COMMITTED: 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
TransactionDefinition.ISOLATION_REPEATABLE_READ: 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
TransactionDefinition.ISOLATION_SERIALIZABLE: 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。
timeout 属性
timeout :事务的超时时间,默认值为 -1。如果超过该时间限制但事务还没有完成,则自动回滚事务。
readOnly 属性
readOnly :指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true。
rollbackFor 属性
rollbackFor :用于指定能够触发事务回滚的异常类型,可以指定多个异常类型。
noRollbackFor属性**
noRollbackFor:抛出指定的异常类型,不回滚事务,也可以指定多个异常类型。
Spring框架的事务管理有哪些优点
· 为不同的事务API 如 JTA,JDBC,Hibernate,JPA 和JDO,提供一个不变的编程模式。
· 为编程式事务管理提供了一套简单的API而不是一些复杂的事务API
· 支持声明式事务管理。
和Spring各种数据访问抽象层很好得集成。