1.事务概念
1.什么是事务
事务是数据库操作最基本单元,逻辑上的一组操作,要么都成功,要么都失败。
2.事务的四个特性(ACID)
- 原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。
- 一致性(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。
- 隔离性(Isolation):可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
- 持久性(Durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久化存储器中。
3.事务操作
- 1.将事务添加到Service层
- 2.在Spring进行事务管理操作
两种方式:编程式事务和声明式事务(常用) - 3.声明式事务管理
注解方式(常用)
基于xml配置方式 - 4.在Spring进行声明式事务管理,底层使用AOP原理
2.声明式事务管理
实例演示:
- 我们将a,b两个人以id,name,money为字段存入数据库
- 我们的操作是:lucy转给marry100元,lucy的money减100,marry的money加100。这其实不是原子性的操作,而是分为了三个步骤:转钱;a-;b+。此时就是需要用到事务的一个场景,我们需要保证三个步骤全部执行才能实现数据的一致性,即要不都执行,要不都不执行。
- 情形一:正常操作(此处不展示)
- 情形二:操作中间加入
int a=10/0;
public TCount exchange(Integer tCount) {
TCount people1=tCountDao.queryById(1);
TCount people2=tCountDao.queryById(2);
int count1=people1.getMoney();
count1-=100;
people1.setMoney(count1);
tCountDao.update(people1);
//执行到此步会中断操作,因为这个语句是错的
int a=10/0;
int count2=people2.getMoney();
count2+=100;
people2.setMoney(count2);
tCountDao.update(people2);
return people1;
}
}
这样的结果可想而知,a的钱减了100并且更新到数据库,然后操作被中断,b的钱依旧是1000,那么a的100元就无辜的消失了。此时,我们加入事务管理,来看看效果。
- 情形三:我们在方法头加入
@Transactional()
注解,表明我这是一个事务的方法。
@Transactional
public TCount exchange(Integer tCount) {
TCount people1=tCountDao.queryById(1);
TCount people2=tCountDao.queryById(2);
int count1=people1.getMoney();
count1-=100;
people1.setMoney(count1);
tCountDao.update(people1);
int a=10/0;
int count2=people2.getMoney();
count2+=100;
people2.setMoney(count2);
tCountDao.update(people2);
return people1;
}
}
加了事务后,我们方法内的每一步都会去执行,如果有一个执行失败,则全部取消执行,这样就不会发生数据丢失的情况了。
3.@Transactional注解信息
-
使用这个注解的类或者方法表示该类里面的所有方法或者这个方法的事务由spring处理,来保证事务的原子性,即是方法里面对数据库操作,如果失败则spring负责回滚操作,成功则提交操作。
-
@Transactional 可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。
-
@Transactional 注解应该只被应用到 public 方法上,如果你在 protected、private 或者默认可见性的方法上使用 @Transactional 注解,这将被忽略,也不会抛出任何异常。
-
属性信息