1.编程式事务:
由程序员编程事务控制代码,OpenSessionlnView编程式事务
2.声明式事务:
事务控制代码已经由Spring写好,程序员只需要声明出哪些方法需要进行事务控制和如何进行事务控制。
这里讲解的是 注解配置事务,如果想去理解XML的同学 可以看看其它的 这里只讲解注解配置的哈
第一步:编写xml
注解的事务配置
1.配置JDBC事务管理器
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransationManager">
<property name="dataSource" ref="dataSource"/>
</bean>
2.开启事务注解驱动
<tx:annotation-driven transaction-manager="txManager"/>
第二步:编写Service业务类
@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.Default,readOnly=true,rollback-for=Exception.class)
public class UserServiceImpl implements UserSerivce{
}
小伙伴们看到这里 可能对注解里面的这么多属性懵比, 别担心,接下来我们一个个慢慢讲。
propagation :它表示控制事务传播行为
当一个具有事务控制的方法被另一个有事务控制的方法调用后,需要如何管理事务呢(新建事务?在事务中执行?把事务挂起?报异常?)
REQUIRED(默认值):如果当前有事务,就在事务中执行,如果当前没有事务,新建一个事务
SUPPORTS:如果当前有事务就在事务中执行,如果当前没有事务,就在非事务状态下执行。
MANDATORY:必须在事务内部执行,如果当前有事务,就在事务中执行,如果没有事务,就报错
REQUIRES_NEW:必须在事务中执行,如果当前没有事务,新建事务,如果当前有事务,把当前事务挂起
NOT_SUPPORTED:必须在非事务下执行,如果当前没有事务,正常执行,如果当前有事务,把当前事务挂起。
NEVER:必须在非事务状态下执行,如果当前没有事务,正常执行,如果当前有事务,报错
NESTED:必须在事务状态下执行,如果没有事务,新建事务,如果当前有事务,创建一个嵌套事务
isolation:它表示事务隔离级别
在多线程或并发访问下如何保证访问到的数据具有完整性的,
1.1 脏读:
一个事务读取到另一个事务中未提交的数据,另一个事务中的数据可能进行了改变,此时A事务
读取的数据可能和数据库中数据是不一致的,此时认为数据是脏数据,读取脏数据过程叫做脏读。
1.2 不可重复读:
- 主要针对的是某行数据(或行中某列)
- 主要针对的操作是修改操作
- 两次读取在同一个事务内
- 当事务A第一次读取事务后,事务B对事务A读取的数据进行修改,事务A再次读取的数据和之前读取的收据不一致,过程不可重复读
1.3 幻读:
- 主要针对的操作是新增或删除
- 两次事务的结果
- 事务A按照特定条件查询出结果,事务B新增了一条负责条件的数据,事务A中查询的数据和数据库中的数据不一致的,事务A好像出现了幻觉,这种情况称为幻读.
取值:
- DEFAULT:默认值,由底层数据库自动判断应该使用什么隔离界别
- READ_UNCOMMITTED:可以读取未提交数据,可能出现脏读,不重复读,幻读。(效率最高)
- READ_COMMITTED:只能读取其它事务已提交数据,可以防止脏读,可能出现不可重复读和幻读
- REPEATABLE_READ:读取的数据被添加锁,防止其它事务去修改此数据,可以防止不可重复读,脏读,可能出现幻读。
- SERIALIZABLE:排队操作对整个表添加锁,一个事务在操作数据时,另一个事务等待事务操作完成后才能操作这个表。(最安全的,效率最低的)
readOnly:它表示是否为只读事务
取值:true false
如果为true告诉数据库此事务为只读事务,数据化优化,会对性能有一定提升,所以只要是查询的方法,建议使用此数据
如果为false,事务需要提交的事务,建议新增,删除,修改时候使用。
rollback-for:它表示事务的回滚
取值:异常类型
当出现什么异常时需要进行回滚,给定该属性值,手动抛异常一定要给属性值,当程序值不是用户想要的时候,可以使用手动抛出异常,然后在进行回滚。
public int updaUsers(Users users){
insert(users);
throw new Exception();
}
public int inseUser(User user){
if(insert(users)>0){
}else{
throw new RuntimeException();
}
}
希望大家下去时候 能够多看看,事务这个东西也是经常用到的,因为就像你去存钱一样,如果你钱刚刚在存放ATM机子里,放了十张,突然断电了,如果没有事务 它不知道你放了几张,从0开始,那么你是不是很崩溃呢,如果它断电时候 立马回滚,其实你就把回滚理解成返回上一步,返回到还未断电的时候,因为断电就会有异常,就返回到异常之上,就会发现 你的十张钱数据 还是完好的,所以 事务用的是非常之多的。