2、使用注解
2.1、注解类
注解类表示在该类中的所有方法都开启事务
@Transactional(propagation = Propagation.REQUIRED)
@Service("addUserImpl1")
public class AddUserImpl1 implements IUser1 {
@Override
public void addUser1() {
User user=new User();
user.setSn("aa");
user.setCn("bb");
user.setSex(null);
personMapper.insert(user);
}
}
2.2、注解方法
注解方法表示指定该方法开启事务
@Service("addUserImpl1")
public class AddUserImpl1 implements IUser1 {
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void addUser1() {
User user=new User();
user.setSn("aa");
user.setCn("bb");
user.setSex(null);
personMapper.insert(user);
}
}
二、事务的传播机制
1、PROPAGATION.REQUIRED (默认)
支持当前事务,如果当前没有事务,则新建事务
如果当前存在事务(外层方法存在事务),则加入当前事务,合并成一个事务
如果上下文中已经存在事务,那么就加入到事务中执行,如果当前上下文中不存在事务,则新建事务执行。所以这个级别通常能满足处理大多数的业务场景
外层事务:@Transactional(propagation = Propagation.*)或没有事务
内层事务:@Transactional(propagation = Propagation.REQUIRED)
外层事务调用内层事务
2、Propagation.REQUIRES_NEW如果外层有事务(当前事务),则内层事务加入到外层事务,一块提交,一块回滚(如果内层出现异常且不捕获,此时外层不能捕获该异常,因为 rollback-only = true 必须进行回滚,所以内外层一起回滚(此情况可改为 SUPPORT );如果内层事务捕获异常,则内外层事务不用回滚)。如果外层没有事务,新建一个事务执行(此时只有内层有事务,内外层互不影响;内层或外层无论谁出现异常且没有被捕获都不会影响到对方)
新建事务,如果当前存在事务,则把当前事务挂起
这个方法会独立提交事务,不受调用者的事务影响,父级异常,它也是正常提交
外层事务:@Transactional(propagation = Propagation.*)或没有事务
内层事务:@Transactional(propagation = Propagation.REQUIRES_NEW)
外层事务调用内层事务
3、Propagation.NESTED无论外层是否有事务,都会在内层中创建一个事务。当内层事务出现异常且该异常往外层抛时,内层事务回滚;如果外层没有对内层抛出的异常进行捕获,则外层有事务就回滚;反之不回滚;当内层事务出现异常并捕获该异常时,则内外层都不用进行回滚
总结:内外层相互独立,如果某一层中出现异常但没有捕获异常,则该层进行回滚;如果都没有异常或已捕获异常则正常提交
如果当前存在事务,它将会成为外层事务的一个子事务,方法结束后并没有提交,只有等外层事务结束才提交
如果外层没有事务,则新建事务
如果它异常,父级可以捕获它的异常而不进行回滚,正常提交
但如果外层异常,内层必然回滚(外层有事务的情况下),这就是和 REQUIRES_NEW 的区别
如果当前存在事务,则加入事务
如果当前不存在事务,则以非事务方式运行
以非事务方式运行
如果当前存在事务,则把当前事务挂起
如果当前存在事务,则运行在当前事务中
如果当前无事务,则抛出异常,也即父级方法必须有事务
以非事务方式运行,如果当前存在事务,则抛出异常,即父级方法必须无事务
三、其他参数 1、isolation
A、脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据
B、不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。
C、幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。
小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表
2、readonly是否为只读事务, 默认 false
3、rollbackFor指定回滚的异常类型,遇到时必须回滚
如:
rollbackFor = {NullPointerException.class,ArrayIndexOutOfBoundsException.class}
4、rollbackForClassName
指定回滚的异常类名,遇到时必须回滚
如:
rollbackForClassName = {"NullPointerException","ArrayIndexOutOfBoundsException"}
5、noRollbackFor
指定不用回滚的异常类型,遇到时不用回滚
如:
noRollbackFor = {NullPointerException.class,ArrayIndexOutOfBoundsException.class}
6、noRollbackForClassName
指定不用回滚的异常类名,遇到时不用回滚
如:
noRollbackForClassName= {"NullPointerException","ArrayIndexOutOfBoundsException"}
7、timeout
事务超时时间
参考文章



