1、@Transactional使用位置
Ⅱ 写在接口方法上,该接口的所有实现类的该方法都会有事务;
Ⅰ 写在实现类上,该类中的所有方法都会有事务;
Ⅱ 写在实现类方法上,该方法上有事务。
建议:写在实现类或实现类的方法上。
2、PlatformTransactionManager
PlatformTransactionManager是哗耐敏Spring中的事务管理接口,具体如下:
3、DataSourceTransactionManager
Spring中JDBC事务管理实现类是DataSourceTransactionManager,所以我们使用MyBatis时,如果需要进行事务管理则配置该事务管理即可。
1、基础准备
jdbc.properties如下:
JdbcConfig如下:
2、测试
1、相关注解
配置类注解,定义在配置类上。
设置当前Spring环境中开启注解式事务支持。
接口、类、方法注解,定义在接口、类、方法上。
为当前业务层方法添加事务(如果设置在类或接口上方则类或接口中所有方法均添加事务)。
2、事务角色
发起事务方,在Spring中通常指代业务层开启事务的方法。
加入事务方,在亩败Spring中通乱枝常指代数据层方法,也可以是业务层方法。
3、@Transactional常用属性
true只读事务,false读写事务,增删改要设为false,查询设为true。
设置超时时间单位秒,在多长时间之内事务没有提交成功就自动回滚,-1表示不设置超时时间。
当出现指定异常进行事务回滚。
4、事务传播行为
比如上述测试案例中,我们给log方法上的@Transactional设置了传播属性为REQUIRES_NEW,表示当前事务协调员会自己开启一个事务。并不会因为transfer发生回滚而回滚。
Ⅰ REQUIRED(默认);
Ⅱ SUPPORTS;
Ⅲ MANDATORY;
Ⅳ REQUIRES_NEW;
Ⅴ NOT_SUPPORTED;
Ⅵ NEVER;
Ⅶ NESTED。
以上即为Spring AOP-事务管理的全部内容,感谢阅读。
1、xml文件头部需要添加spring的相关支持:渣搜 2、配置事务管理器
3、配置需要加入事务的方法规则,或者说是一个切面
<!-- 定义事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!--使用注释事务 -->
<tx:annotation-driven transaction-manager="transactionManager" />
事物配置中有哪些属性可以配置
(1)事务的传播性:@Transactional(propagation=Propagation.REQUIRED)
如果有事务, 那么加入事务, 没有的话新建一个(默认情况下)
(2)事务的超时性:@Transactional(timeout=30) //默认是30秒
注如轮历意这里说的是事务的超时性而不是Connection的超时性,这两个是有区别的
(3)事务的隔离级别:@Transactional(isolation = Isolation.READ_UNCOMMITTED)
读取未提交数据(会出现脏读, 不可重复读) 基本不使用
(4)回滚:
指定单一异常类:@Transactional(rollbackFor=RuntimeException.class)
指定多个异常类:@Transactional(rollbackFor={RuntimeException.class, Exception.class})
该属性用于设置需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则进行事务回滚。
(5)只读:@Transactional(readOnly=true)
该属性用于设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false。
例如:
@Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class,timeout=1,isolation=Isolation.DEFAULT)
public void saveUser(Map<String, String>map) throws Exception {
System.out.println("方法开始")
for (int i = 0i <500000i++) {
System.out.println("*")
}
System.out.println("进入保存")
userDao.saveUser(map)
System.out.println("退出保存")
}
解释说明
事务的传播级别定义的是事务的控制范围,主要是父子事务之间的相互影响关系;事务的隔离级别定义的是事务读写的控制范围,主要是两个事务之间的相互影响关系。
传播级别:
1)、REQUIRED
如果当前方法已经在事务中,那么就以父事务执行,不需要新建事务;如果当前方法不在事务中,那么就为当前方法新建事务。桐纯回滚情况:父子方法中任何地方出现问题,都会全部回滚。
2)、SURPPORTED
如果当前方法已经在事务中,那么就以当前事务执行;如果当前方法不再事务中,那么就以非事务方式运行。如果运行在事务中,那么只要出现异常都会回滚。
3)、NOT_SURPPORTED
如果当前方法已经在事务中,那么就挂起当前事务,以非事务方式运行,方法执行完毕后,恢复事务;如果当前方法不再事务中,那么就以非事务方式执行。
4)、MANDATORY
强制以事务方式执行,如果当前方法不在事务中,那么会抛出异常。
5)、NEVER
与MANDATORY相反,强制以非事务方式执行,如果当前方法在事务中,那么会抛出异常。
6)、REQUIRED_NEW
与REQUIRED不同的是,无论该方法当前是不是在事务中,都会为自己新建一个事务。如果当前已经在事务中,那么会挂起父事务,为自己新建一个事务。父事务不影响它子事务的提交和回滚。
7)、NESTED
嵌套事务。理解Nested的关键是savepoint。他与PROPAGATION_REQUIRES_NEW的区别是,PROPAGATION_REQUIRES_NEW另起一个事务,将会与他的父事务相互独立,而Nested的事务和他的父事务是相依的,他的提交是要等和他的父事务一块提交的。也就是说,如果父事务最后回滚,他也要回滚的。而Nested事务的好处是他有一个savepoint。
例如:
ServiceA {
/**
* 事务属性配置为 PROPAGATION_REQUIRED
*/
void methodA() {
try {
//savepoint
ServiceB.methodB()//PROPAGATION_NESTED 级别
} catch (SomeException) {
// 执行其他业务, 如 ServiceC.methodC()
}
}
}
也就是说ServiceB.methodB失败回滚,那么ServiceA.methodA也会回滚到savepoint点上,ServiceA.methodA可以选择另外一个分支,比如ServiceC.methodC,继续执行,来尝试完成自己的事务。
原文链接:https://blog.csdn.net/wgh1015398431/java/article/details/52861048
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)