这里写目录标题
一级目录
二级目录
三级目录
一 Alibaba Java Coding Guidelines plugin的提示

二简单回顾Java Exception
Throwable: 有两个重要的子类:Exception(异常)和 Error(错误),二者都是 Java 异常处理的重要子类,各自都包含大量子类。异常和错误的区别是:异常能被程序本身可以处理,错误是无法处理。
需要注意的是
sqlException是属于非运行时异常!

除Error的一方面来讲,我们可以将异常(Exception)分为
运行时异常(RuntimeException)非运行时异常(Exception中除了RuntimeException及其子类以外的)。
另一方面整体来讲,我们可以将异常分为受控异常(checked exceptions)和不受控异常(unchecked exceptions)。
受控异常(checked exceptions):就是非运行时异常,即Exception中除了RuntimeException及其子类以外的。
不受控异常(unchecked exceptions):RuntimeException和Error。
如果不对运行时异常进行处理,那么出现运行时异常之后,要么是线程中止,要么是主程序终止。
如果不想终止,则必须捕获所有的运行时异常,决不让这个处理线程退出。队列里面出现异常数据了,正常的处理应该是把异常数据舍弃,然后记录日志。不应该由于异常数据而影响下面对正常数据的处理。
非运行时异常是RuntimeException以外的异常,类型上都属于Exception类及其子类。如IOException、SQLException等以及用户自定义的Exception异常。对于这种异常,JAVA编译器强制要求我们必需对出现的这些异常进行catch并处理,否则程序就不能编译通过。所以,面对这种异常不管我们是否愿意,只能自己去写一大堆catch块去处理可能的异常。
三 简单回顾 事务管理方式
事务具有4个特征,分别是原子性、一致性、隔离性和持久性,简称事务的ACID特性;
1、原子性(atomicity)
一个事务要么全部提交成功,要么全部失败回滚,不能只执行其中的一部分操作,这就是事务的原子性
2、一致性(consistency)
事务的执行不能破坏数据库数据的完整性和一致性,一个事务在执行之前和执行之后,数据库都必须处于一致性状态。
如果数据库系统在运行过程中发生故障,有些事务尚未完成就被迫中断,这些未完成的事务对数据库所作的修改有一部分已写入物理数据库,这是数据库就处于一种不正确的状态,也就是不一致的状态
3、隔离性(isolation)
事务的隔离性是指在并发环境中,并发的事务时相互隔离的,一个事务的执行不能不被其他事务干扰。不同的事务并发操作相同的数据时,每个事务都有各自完成的数据空间,即一个事务内部的操作及使用的数据对其他并发事务时隔离的,并发执行的各个事务之间不能相互干扰。
在标准SQL规范中,定义了4个事务隔离级别,不同的隔离级别对事务的处理不同,分别是:未授权读取,授权读取,可重复读取和串行化
1、读未提交(Read Uncommited),该隔离级别允许脏读取,其隔离级别最低;比如事务A和事务B同时进行,事务A在整个执行阶段,会将某数据的值从1开始一直加到10,然后进行事务提交,此时,事务B能够看到这个数据项在事务A操作过程中的所有中间值(如1变成2,2变成3等),而对这一系列的中间值的读取就是未授权读取
2、授权读取也称为已提交读(Read Commited),授权读取只允许获取已经提交的数据。比如事务A和事务B同时进行,事务A进行+1操作,此时,事务B无法看到这个数据项在事务A操作过程中的所有中间值,只能看到最终的10。另外,如果说有一个事务C,和事务A进行非常类似的操作,只是事务C是将数据项从10加到20,此时事务B也同样可以读取到20,即授权读取允许不可重复读取。
3、可重复读(Repeatable Read)
就是保证在事务处理过程中,多次读取同一个数据时,其值都和事务开始时刻是一致的,因此该事务级别禁止不可重复读取和脏读取,但是有可能出现幻影数据。所谓幻影数据,就是指同样的事务操作,在前后两个时间段内执行对同一个数据项的读取,可能出现不一致的结果。在上面的例子中,可重复读取隔离级别能够保证事务B在第一次事务操作过程中,始终对数据项读取到1,但是在下一次事务操作中,即使事务B(注意,事务名字虽然相同,但是指的是另一个事务操作)采用同样的查询方式,就可能读取到10或20;
4、串行化
是最严格的事务隔离级别,它要求所有事务被串行执行,即事务只能一个接一个的进行处理,不能并发执行。
4、持久性(durability)
一旦事务提交,那么它对数据库中的对应数据的状态的变更就会永久保存到数据库中。–即使发生系统崩溃或机器宕机等故障,只要数据库能够重新启动,那么一定能够将其恢复到事务成功结束的状态
所以事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性。
spring支持编程式事务管理和声明式事务管理两种方式。
编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。
声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
声明式事务管理也有两种常用的方式,一种是基于tx和aop名字空间的xml配置文件,另一种就是基于@Transactional注解。显然基于注解的方式更简单易用,更清爽。
使用说明
当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。
@Transactional注解的全部属性详解
@Transactional属性
属性 类型 描述
value String 可选的限定描述符,指定使用的事务管理器
propagation enum: Propagation 可选的事务传播行为设置
isolation enum: Isolation 可选的事务隔离级别设置
readOnly boolean 读写或只读事务,默认读写
timeout int (in seconds granularity) 事务超时时间设置
rollbackFor Class对象数组 必须继承自Throwable 导致事务回滚的异常类数组
rollbackForClassName 类名数组 必须继承自Throwable 导致事务回滚的异常类名字数组
noRollbackFor Class对象数组 必须继承自Throwable 不会导致事务回滚的异常类数组
noRollbackForClassName 类名数组 必须继承自Throwable 不会导致事务回滚的异常类名字数组
四Spring框架Transactional注解的rollback属性介绍
Spring框架的事务管理默认地只在发生不受控异常(RuntimeException和Error)时才进行事务回滚。也就是说,当事务方法抛出受控异常(checked exceptions) Exception中除了RuntimeException及其子类以外的时侯 (例如:sqlException)不会进行事务回滚。
这时rollbackFor属性在这里就可以发挥它的作用了!
在@Transactional注解中如果不配置rollbackFor属性,那么事物只会在遇到RuntimeException的时候才会回滚,加上rollbackFor=Exception.class,可以让事物在遇到非运行时异常时也回滚。
在项目中,@Transactional(rollbackFor=Exception.class),如果类加了这个注解,那么这个类里面的方法抛出异常,就会回滚,数据库里面的数据也会回滚,因为sqlException属于Exception
在类或方法前注解配置@Transactional(rollbackFor=Exception.class)就可以实现:
当发生受控异常(checked exceptions)时,事务也进行回滚。
五 加入rollback属性之后的service代码
package fengbo.service;
import fengbo.dao.AccountMapper;
import fengbo.entity.Account;
import fengbo.entity.AccountExample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* Created by @author LiuChunhang on 2020/7/15.
*/
@Service
public class AccountService implements AccountServiceInterface {
@Autowired
public AccountMapper accountMapper;
public AccountMapper getAccountMapper() {
return accountMapper;
}
public void setAccountMapper(AccountMapper accountMapper) {
this.accountMapper = accountMapper;
}
@Override
@Transactional(rollbackFor = Exception.class)
public int register(Account account) {
int insert = accountMapper.insert(account);
return insert;
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean validate(Account account) {
boolean flag = false;
String acc = account.getAccount();
String pass = account.getPassword();
AccountExample accountExample = new AccountExample();
accountExample.createCriteria().andAccountEqualTo(acc);
List<Account> accs1 = accountMapper.selectByExample(accountExample);
accountExample.createCriteria().andPasswordEqualTo(pass);
List<Account> accs2 = accountMapper.selectByExample(accountExample);
for (Account acc1 : accs1) {
if (accs2.contains(acc1)) {
flag = true;
} else {
flag = false;
}
}
System.out.println(flag);
return flag;
}
}

3172

被折叠的 条评论
为什么被折叠?



