spring学习总结015 --- spring事务

Posted sniffs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring学习总结015 --- spring事务相关的知识,希望对你有一定的参考价值。

本文使用的是spring + mybatis,数据库用的是mysql,说事务的传播行为之前先介绍一个SSM开发中很好用的一个IDEA插件 --- Easy Code

Easy Code插件

该插件用来基于数据库表来生成开发中用到的entiry类、mapper接口、mapper.xml等代码,免去了手工定义的麻烦

使用方法:

1、IDEA连接mySql,选中数据库表然后右键,选择EasyCode -> Generate Code

技术图片

2、在弹出的对话框中填写要生成的代码及所在的包名

技术图片

spring事务

事务的特性

  • 原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。
  • 一致性(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。
  • 隔离性(Isolation):可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
  • 持久性(Durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久化存储器中。

编程式事务管理

使用TransactionTemplate或者PlatformTransactionManager -----  这种方式没怎么用过,不知道咋写例子

声明式事务管理

声明式事务基于AOP实现,本质是对方法进行拦截,在方法执行前植入或者创建事务,在方法执行后根据执行结果做事务的提交或者回滚;

用法:

1、声明c3p0数据源为bean

<bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource">
    <property name="user" value="${user}" />
    <property name="password" value="${password}" />
    <property name="driverClass" value="${driver}" />
    <property name="jdbcUrl" value="${url}" />
</bean>

2、声明一个基于数据源的事务管理器

<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>

3、配置声明支持事务注解

<tx:annotation-driven transaction-manager="transactionManager" />

4、方法使用@Transactional注解修饰

注意:spring手册里明确写道,@Transactional注解用于修饰公共方法并且被外部代码类调用的时候事务才生效;如果修饰私有或者保护方法,不会报错,但是事务也不会生效;原因:transactional标签用于将对应包装的bean设置成一个新的代理bean对象供外部使用,就是说外部调用这个proxy bean的公共方法时先会调用开启事务等的切面工作,若设置成私有方法只能类内用this指针调用,这样被调用的bean是其本身,不是proxy对象,因此没有transactional切面的意义

举例:

public void createUser(@NonNull TableUser tableUser) {
    TableUserDao tableUserDao = sqlSessionTemplate.getMapper(TableUserDao.class);
    createUser(tableUser, tableUserDao);
}

@Transactional
private void createUser(TableUser tableUser, TableUserDao tableUserDao) {
    tableUserDao.insert(tableUser);
    throw new RuntimeException();
}
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean.xml");

TableUserService service = context.getBean(TableUserService.class);

service.createUser(TableUser.builder().id(2).age(22).name("bale2").build());
}

main方法执行后,可以看到方法抛出异常,但是数据没有回滚:

技术图片

如果非要用在private修饰的方法上,可以结合AspectJ来实现

spring事务传播行为

技术图片

 

spring事务隔离级别

技术图片

 

以上是关于spring学习总结015 --- spring事务的主要内容,如果未能解决你的问题,请参考以下文章

Sprin学习一

Spring Boot Sample 015之spring-boot-error-exception

Spring Boot Sample 015之spring-boot-error-exception

Spring Boot2(015):JSON

015.C#基础总结

015-Spring Boot 定制和优化内嵌的Tomcat