4.115 Spring的事务管理
-
事物的概述
-
原子性:要不成功,要不失败不可再分
-
一致性:转钱A-5000B+5000
-
隔离性:多个事务不相互影响
-
持久性:事务提交后就已经在数据库中完成
-
Spring支持两种类型的事务管理实现方式
-
编程式事务管理:这意味你通过编程(手动)的方式管理事务,给你带来极大的灵活性,但是难维护。
-
Jdbc代码:Conn.setAutoCommite(false); // 设置手动控制事务
-
Hibernate代码:Session.beginTransaction(); // 开启一个事务
-
比较灵活,但开发起来比较繁琐: 每次都要开启、提交、回滚
-
声明式事务管理:这意味着你可以将业务代码和事务管理分离,你只需用Spring注解和XML配置来管理事务。
-
Spring提供了对事务控制的实现。用户如果想用Spring的声明式事务管理,只需要在配置文件中配置即可; 不想使用时直接移除配置。这个实现了对事务控制的最大程度的解耦。
-
Spring声明式事务管理,核心实现就是基于Aop。
-
因为aop拦截的是方法,只能给整个方法应用事务,不可以对方法的某几行应用事务
-
Spring声明式事务管理器类:
-
Jdbc技术:DataSourceTransactionManager
-
Hibernate技术:HibernateTransactionManager
-
事物是程序运行如果没有错误,会自动提交事物,如果程序运行发生异常,则会自动回滚。如果使用了try捕获异常时.一定要在catch里面手动回滚。事物手动回滚代码
-
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
-
声明事务实现方式
-
XML方式实现
-
注解方式实现
-
必须引入Aop相关的jar文件
-
bean.xml中指定注解方式实现声明式事务管理以及应用的事务管理器类
-
在需要添加事务控制的地方,写上: @Transactional
-
@Transactional注解:
-
应用事务的注解
-
定义到方法上: 当前方法应用spring的声明式事务
-
定义到类上: 当前类的所有的方法都应用Spring声明式事务管理;
-
定义到父类上: 当执行父类的方法时候应用事务。
-
实现原理
-
Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。
-
事物底层实现通过AOP环绕通知实现
-
使用事物时,一定要将异常抛出外部,不然AOP环绕通知获取不到异常不能够回滚。
-
Spring框架的事务管理有哪些优点
-
为不同的事务API 如 JTA,JDBC,Hibernate,JPA 和JDO,提供一个不变的编程模式。
-
为编程式事务管理提供了一套简单的API而不是一些复杂的事务API
-
支持声明式事务管理。
-
和Spring各种数据访问抽象层很好得集成。
-
Spring事务隔离
-
首先说明一下事务并发引起的三种情况:
-
Dirty Reads 脏读:一个事务正在对数据进行更新操作,但是更新还未提交,另一个事务这时也来操作这组数据,并且读取了前一个事务还未提交的数据,而前一个事务如果操作失败进行了回滚,后一个事务读取的就是错误数据,这样就造成了脏读。
-
Non-Repeatable Reads 不可重复读:一个事务多次读取同一数据,在该事务还未结束时,另一个事务也对该数据进行了操作,而且在第一个事务两次次读取之间,第二个事务对数据进行了更新,那么第一个事务前后两次读取到的数据是不同的,这样就造成了不可重复读。
-
Phantom Reads 幻像读:第一个数据正在查询符合某一条件的数据,这时,另一个事务又插入了一条符合条件的数据,第一个事务在第二次查询符合同一条件的数据时,发现多了一条前一次查询时没有的数据,仿佛幻觉一样,这就是幻像读。
-
非重复度和幻像读的区别:非重复读是指同一查询在同一事务中多次进行,由于其他提交事务所做的修改或删除,每次返回不同的结果集,此时发生非重复读。幻像读是指同一查询在同一事务中多次进行,由于其他提交事务所做的插入操作,每次返回不同的结果集,此时发生幻像读。表面上看,区别就在于非重复读能看见其他事务提交的修改和删除,而幻像能看见其他事务提交的插入。
-
spring 有五大隔离级别,默认值为 ISOLATION_DEFAULT(使用数据库的设置),其他四个隔离级别和数据库的隔离级别一致:
-
ISOLATION_DEFAULT:用底层数据库的设置隔离级别,数据库设置的是什么我就用什么;
-
ISOLATION_READ_UNCOMMITTED:未提交读,最低隔离级别、事务未提交前,就可被其他事务读取(会出现幻读、脏读、不可重复读);
-
ISOLATION_READ_COMMITTED:提交读,一个事务提交后才能被其他事务读取到(会造成幻读、不可重复读),SQL server 的默认级别;
-
ISOLATION_REPEATABLE_READ:可重复读,保证多次读取同一个数据时,其值都和事务开始时候的内容是一致,禁止读取到别的事务未提交的数据(会造成幻读),MySQL 的默认级别;
-
ISOLATION_SERIALIZABLE:序列化,代价最高最可靠的隔离级别,该隔离级别能防止脏读、不可重复读、幻读。
-
Spring事务传播属性(Propagation)
-
Propagation(key属性确定代理应该给哪个方法增加事务行为。这样的属性最重要的部份是传播行为。)有以下选项可供使用:
-
* PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
-
* PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。(如果当前有事物,我就用当前事物,如果当前没有事物,就以非事物进行执行)
-
* PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
-
* PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
-
* PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
-
* PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
-
Spring集成事务
-
Spring 通过提供ORM模块,支持我们在直接JDBC之上使用一个对象/关系映射映射(ORM)工具,Spring 支持集成主流的ORM框架,如Hiberate,JDO和 iBATIS,JPA,TopLink,JDO,OJB 。Spring的事务管理同样支持以上所有ORM框架及JDBC。
-
保证数据库代码的简洁,并能避免数据库资源错误关闭导致的问题,它在各种不同的数据库的错误信息之上,提供了一个统一的异常访问层。它还利用Spring的AOP 模块给Spring应用中的对象提供事务管理服务。
-
spring DAO 有什么用?
-
Spring DAO(数据访问对象) 使得 JDBC,Hibernate 或 JDO 这样的数据访问技术更容易以一种统一的方式工作。这使得用户容易在持久性技术之间切换。它还允许您在编写代码时,无需考虑捕获每种技术不同的异常。
-
spring JDBC API 中存在哪些类?
-
JdbcTemplate
-
JdbcTemplate 类提供了很多便利的方法解决诸如把数据库数据转变成基本数据类型或对象,执行写好的或可调用的数据库操作语句,提供自定义的数据错误处理。
-
SimpleJdbcTemplate
-
NamedParameterJdbcTemplate
-
SimpleJdbcInsert
-
SimpleJdbcCall
努力不一定成功,但不努力一定会失败~