Spring AOP事务管理
1 Spring事务简介
(1) 事务作用:在数据层保障一系列的数据库操作同成功同失败。
(2) Spring事务作用:在数据层或业务层保障一系列的数据库操作同成功同失败。
(3) Spring为了管理事务,提供了一个平台事务管理器
PlatformTransactionManager。public interface PlatformTransactionManager{
void commit(Transactionstatus status)throws TransactionException;
//commit是用来提交事务。
void rollback(Transactionstatus status)throws TransactionException;
//rollback是用来回滚事务。
}
(4) PlatformTransactionManager只是一个接口,Spring还为其提供了一个具体的实现:
public class DataSourceTransactionManager{}(5) 从名称上可以看出,我们只需要给它一个DataSource对象,它就可以帮你去在业务层管理事务。
(6) 其内部采用的是JDBC的事务。所以说如果你持久层采用的是JDBC相关的技术,就可以采用这个事务管理器来管理你的事务。
(7) 而Mybatis内部采用的就是JDBC的事务,所以Spring整合Mybatis就采用的这个DataSourceTransactionManager事务管理器。
2 快速入门
(1) 在需要被事务管理的方法上添加注解
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountDao accountDao;
@Transactional
public void transfer(String out,String in ,Double money) {
accountDao.outMoney(out,money);
int i = 1/0;
//模拟异常
accountDao.inMoney(in,money);
}
}
(2) 在JdbcConfig类中配置事务管理器
public class JdbcConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String userName;
@Value("${jdbc.password}")
private String password;
@Bean
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(userName);
ds.setPassword(password);
return ds;
}
//配置事务管理器,mybatis使用的是jdbc事务。
//注意:事务管理器要根据使用技术进行选择,Mybatis框架使用的是JDBC事务,可以直接使用DataSourceTransactionManager。
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
}
(3) 开启事务注解
//在SpringConfig的配置类中开启。
@Configuration
@ComponentScan("com.itheima")
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class,MybatisConfig.class})
//开启注解式事务驱动
@EnableTransactionManagement
public class SpringConfig {
}
(4) 运行测试类
会发现在转换的业务出现错误后,事务就可以控制回滚,保证数据的正确性。
(5) 注意
@Transactional可以写在接口类上、接口方法上、实现类上和实现类方法上。写在接口类上,该接口的所有实现类的所有方法都会有事务。
写在接口方法上,该接口的所有实现类的该方法都会有事务。
写在实现类上,该类中的所有方法都会有事务。
写在实现类方法上,该方法上有事务。
***建议写在实现类或实现类的方法上。
3 Spring事务角色
(1) 未开启Spring事务管理之前:
AccountDao的outMoney因为是修改操作,会开启一个事务T1。
AccountDao的inMoney因为是修改操作,会开启一个事务T2。
//T1和T2即为事务协调员。
AccountService的transfer没有事务。
如果没有抛出异常,则T1和T2都正常提交,数据正确。
如果在两个方法中间抛出异常,T1因为执行成功提交事务,T2因为抛异常不会被执行就会导致数据出现错误。
(2) 开启Spring事务管理之后:
transfer上添加了
@Transactional注解,在该方法上就会有一个事务T。//T为事务管理员。
AccountDao的outMoney方法的事务T1加入到transfer的事务T中。
AccountDao的inMoney方法的事务T2加入到transfer的事务T中。
这样就保证他们在同一个事务中,当业务层中出现异常,整个事务就会回滚,保证数据的准确性。
(3) 通过上面例子的分析,我们就可以得到如下概念:
事务管理员:发起事务方,在Spring中通常指代业务层开启事务的方法。
//即添加了@Transactional注解的方法。
事务协调员:加入事务方,在Spring中通常指代数据层方法,也可以是业务层方法。
//即添加了@Transactional注解的方法中所被调用的dao或service方法。
//两者本质上仍是事务,若因为事务管理员中的异常或某些原因,某个事务协调员所新建事务的代码根本未被执行,事务也不会执行。
(4) 注意
目前的事务管理是基于
DataSourceTransactionManager和SqlSessionFactoryBean使用的是同一个数据源。4 Spring事务属性
(1) 事务属性
<1> readOnly
使用:
@Transactional(readOnly=true)作用:设置是否为只读事务,
true只读事务,false读写事务,增删改要设为false,查询设为true。<2> timeout
使用:
@Transactional(timeout=-1)//永不超时作用:设置事务超时时间,单位秒,在多长时间之内事务没有提交成功就自动回滚,
-1表示不设置超时时间。<3> rollbackFor
使用:
@Transactional(rollbackFor={NullPointException.class})作用:设置事务回滚异常(class类),当出现指定异常进行事务回滚。
//并不是所有的异常都会回滚事务,Spring的事务只会对Error异常和RuntimeException异常及其子类进行事务回顾,其他的异常类型是不会回滚的。
<4> rollbackForClassName
使用:同上,格式为字符串。
@Transactional(rollbackFor={"NullPointException"})作用:设置事务回滚异常(String字符串),等同于
rollbackFor,只不过属性为异常的类全名字符串。<5> noRollbackFor
使用:
@Transactional(noRollbackFor={NullPointException.class})作用:设置事务不回滚异常(class类),当出现指定异常不进行事务回滚。
<6> noRollbackForClassName
使用:同上格式为字符串。
@Transactional(noRollbackFor={"NullPointException"})作用:设置事务不回滚异常(String字符串),等同于
noRollbackFor,只不过属性为异常的类全名字符串。<7> isolation
使用:
@Transactional(isolation=Isolation.DEFAULT)作用:设置事务隔离级别(
DEFAULT、READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ、SERIALIZABLE),详情查看MySQL笔记。<8> propagation
使用:
@Transactional(propagation=Propagation.可选值)作用:设置事务传播行为。
详情见下,事务传播行为。
//上面这些属性都可以在@Transactional注解的参数上进行设置。
(2) 事务传播行为
<1> 事务传播行为
事务协调员对事务管理员所携带事务的处理态度。
<2> 事务传播行为的可选值
<2.1>
REQUIRED(默认)若事务管理员新建事务t,则事务协调员加入事务t。
若事务管理员未开启事务,则事务协调员新建事务t。
<2.1>
REQUIRES_NEW若事务管理员新建事务t1,则事务协调员新建事务t2。
若事务管理员未开启事务,则事务协调员新建事务t。
<2.1>
SUPPORTS若事务管理员新建事务t,则事务协调员加入事务t。
若事务管理员未开启事务,事务协调员也不开启事务。
<2.1>
NOT_SUPPORTED若事务管理员新建事务t,则事务协调员不开启事务。
若事务管理员未开启事务,事务协调员也不开启事务。
<2.1>
MANDATORY若事务管理员新建事务t,则事务协调员加入事务t。
若事务管理员未开启事务,则程序报错error。
<2.1>
NEVER若事务管理员开启事务,则程序报错error。
若事务管理员未开启事务,则事务协调员也不开启事务。
<2.1>
NESTED设置savePoint,一且事务回滚,事务将回滚到savePoint处,交由客户响应提交/回滚。
//对于我们开发实际中使用的话,因为默认值需要事务是常态的。根据开发过程选择其他的就可以了,例如案例中需要新事务就需要手工配置。

浙公网安备 33010602011771号