spring事务使用注解

六、声明事务

1.基于注解方式做事务处理

环境搭建:

1).导入相关依赖

* 数据源,数据库驱动、Spring-jdbc模块
	  <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-jdbc</artifactId>
          <version>4.3.12.RELEASE</version>
      </dependency>
      <dependency>
          <groupId>c3p0</groupId>
          <artifactId>c3p0</artifactId>
          <version>0.9.1.2</version>
      </dependency>
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-tx</artifactId>
          <version>4.3.12.RELEASE</version>
      </dependency>

2).配置数据源、JdbcTemplate(Spring提供简化数据源操作)操作数据源

@EnableTransactionManagement
@ComponentScan("com.it.tx")
@Configuration
public class TxConfig {


    //数据源
    @Bean
    public DataSource dataSource() throws Exception{
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser("root");
        dataSource.setPassword("");
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");

        return dataSource;
    }


    //
    @Bean
    public JdbcTemplate jdbcTemplate() throws Exception{
        //spring对@Configuration会特殊处理,给容器中加组件的方法多次调用都只是从容器中找组件
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
        return jdbcTemplate;
    }

    //注册事务管理器
    @Bean
    public PlatformTransactionManager platformTransactionManager() throws Exception{
        return new DataSourceTransactionManager(dataSource());
    }
}

3).给方法标注上@Transactional 表示当前方法是一个事务方法

4).@EnableTransactionManagement开启基于注解的事务管理功能:

5).配置事务管理器来控制事务

  • dao
@Repository
public class UserDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public void insert(){
        String sql = "INSERT INTO `tbl_user`(username,age) VALUES(?,?);";
        String username = UUID.randomUUID().toString().substring(0, 5);
        jdbcTemplate.update(sql,username,19);
    }
}
  • service
@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    @Transactional//不加事务,数据库就不会回滚,会添加一条记录
    public void insertUser(){
        userDao.insert();
        //otherDao.other();

        System.out.println("插入完成.....");
        int i = 10/0;
    }

}
  • 测试
@Test
public void test01(){

    //1.创建applicationContext
    AnnotationConfigApplicationContext applicationContext =
            new AnnotationConfigApplicationContext(TxConfig.class);


    UserService userService = applicationContext.getBean(UserService.class);
    userService.insertUser();


    applicationContext.close();
}
  • 效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PzeFMMWh-1582949331658)(C:\Users\单少宝宝\AppData\Roaming\Typora\typora-user-images\1582820209773.png)]


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tdDoFdnn-1582949331663)(C:\Users\单少宝宝\AppData\Roaming\Typora\typora-user-images\1582820226230.png)]

此时的数据库中并未添加新的记录,说明 我们的事务管理开始工作了。

2.@EnableTransactionManagement的实现原理:

1)、@EnableTransactionManagement

​ 利用TransactionManagementConfigurationSelector给容器中导入组件。

​ 导入两个组件

​ AutoProxyRegistrar、

​ ProxyTransactionManagementConfiguration

2)、AutoProxyRegistrar:

​ 给容器中注册一个InfrastructureAdvisorAutoProxyCreator组件

​ InfrastructureAdvisorAutoProxyCreator:?

​ 利用重置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器),代理对象执行方法利用拦截器链进行调用;

3)、ProxyTransactionManagementConfiguration 做了什么?

1.给容器中注册事务增强器:
​					事务增强器要用事务注解 的信息,AnnotationTransactionAttributeSource来解析事务注解
			2.事务拦截器:
					TransactionInterceptor:保存了事务属性的信息,事务管理器;
					他是一个MethodInterceptor:
					在目标方法执行的时候:
							执行拦截器链:
							事务拦截器:
									1)、先获取事务相关的属性
									2)、再获取PlatformTransactionManager,如果事先没有添加指定任何
						transactionmanager,最终会从容器中执照类型获取一个PlatformTransactionManager
									3)、执行目标方法
												如果异常,获取到事务管理器,利用事务管理器回滚操作:
												如果正常,利用事务管理器,提交 事务
  • 事务抽象

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hAMqcgWu-1582949331665)(C:\Users\单少宝宝\AppData\Roaming\Typora\typora-user-images\1582868905052.png)]

  • 事务拦截

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OVhC9kSN-1582949331666)(C:\Users\单少宝宝\AppData\Roaming\Typora\typora-user-images\1582869299757.png)]

spring事务使用注解spring事务使用注解 大脑斧 发布了11 篇原创文章 · 获赞 18 · 访问量 4580 私信 关注
上一篇:jdbcTemplate queryForMap与queryForList区别


下一篇:jdbcTemplate实现crud操作(添加、删除、更改操作)