Spring AOP集成jdbc

spring 事务

事务的概念

事务指数据库中多个操作合并在一起形成的操作序列

事务的隔离级

  • 脏读:允许读取未提交的信息

      原因:Read uncommitted
      解决方案: (表级读锁)
    
  • 不可重复读:读取过程中单个数据发生了变化

      解决方案: Repeatable read (行级写锁)
    
  • 幻读:读取过程中数据条目发生了变化

      解决方案: Serializable(表级写锁)
    

事务管理

Spring事务核心对象

spring为业务层提供了整套的事务解决方案

  • PlatformTransactionManager

  • TransactionDefinition

  • TransactionStatus

PlatformTransactionManager平台事务管理器实现类

  • DataSourceTransactionManager 适用于Spring JDBC或MyBatis

  • HibernateTransactionManager 适用于Hibernate3.0及以上版本

  • JpaTransactionManager 适用于JPA

  • JdoTransactionManager 适用于JDO

  • JtaTransactionManager 适用于JTA
    常用方法:

    获取事务 :TransactionStatus getTransaction(TransactionDefinition definition)
    提交事务 :void commit(TransactionStatus status) 
    回滚事务 :void rollback(TransactionStatus status)
    

TransactionDefinition

获取事务定义名称:String getName()
获取事务的读写属性:boolean isReadOnly()
获取事务隔离级别:int getIsolationLevel()
获事务超时时间:int getTimeout()
获取事务传播行为特征:int getPropagationBehavior()

TransactionStatus

获取事务是否处于新开启务状态:boolean iaNewTransaction()
刷新事务状态:void flush()
获取事务是否处于已完成状态:boolean iaCompleted() 
获取事务是否具有回滚存情点:boolean hasSavepoint ()
获取事务是否处于回滚状态:boolean isRollbackOnly()
设置事务处于回滚状态:void setRollbackOnly()

编程式事务

public void transfer(String outName,String inName,Double money){
    //创建事务管理器
    DataSourceTransactionManager dstm = new DataSourceTransactionManager();
    //为事务管理器设置与数据层相同的数据源
    dstm.setDataSource(dataSource);
    //创建事务定义对象
    TransactionDefinition td = new DefaultTransactionDefinition();
    //创建事务状态对象,用于控制事务执行
    TransactionStatus ts = dstm.getTransaction(td);
    accountDao.inMoney(outName,money);
    int i = 1/0;    //模拟业务层事务过程中出现错误
    accountDao.outMoney(inName,money);
    //提交事务
    dstm.commit(ts);
}

使用AOP控制事务

将业务层的事务处理功能抽取出来制作成AOP通知,利用环绕通知运行期动态织入

public Object tx(ProceedingJoinPoint pjp) throws Throwable {
    
    DataSourceTransactionManager dstm = new DataSourceTransactionManager();
    dstm.setDataSource(dataSource);
    TransactionDefinition td = new DefaultTransactionDefinition();
    TransactionStatus ts = dstm.getTransaction(td);
    Object ret = pjp.proceed(pjp.getArgs());
    dstm.commit(ts);
    
    return ret;
}

配置AOP通知类,并注入dataSource

<bean id="txAdvice" class="com.itheima.aop.TxAdvice">
    <property name="dataSource" ref="dataSource"/>
</bean>

使用环绕通知将通知类织入到原始业务对象执行过程中

<aop:config>
    <aop:pointcut id="pt" expression="execution(* *..transfer(..))"/>
    <aop:aspect ref="txAdvice">
        <aop:around method="tx" pointcut-ref="pt"/>
    </aop:aspect>
</aop:config>

声明式事务(XML)

public Object tx(ProceedingJoinPoint pjp) throws Throwable {
    DataSourceTransactionManager dstm = new DataSourceTransactionManager();
    dstm.setDataSource(dataSource);
    TransactionDefinition td = new DefaultTransactionDefinition();
    TransactionStatus ts = dstm.getTransaction(td);
    Object ret = pjp.proceed(pjp.getArgs());
    dstm.commit(ts);

    return ret;
}
<bean id="txAdvice" class="com.itheima.aop.TxAdvice">
	<property name="dataSource" ref="dataSource"/>
</bean>

使用tx命名空间配置事务专属通知类

<tx:advice id="advice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="save*" propagation="REQUIRED"/>
            <tx:method name="add" propagation="REQUIRED"/>
            <tx:method name="delete*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="modify*" propagation="REQUIRED"/>
            <tx:method name="remove*" propagation="REQUIRED"/>
            <tx:method name="*" propagation="NOT_SUPPORTED" read-only="true"/>
        </tx:attributes>
    </tx:advice>

使用aop:advisor在AOP配置中引用事务专属通知类

 <!--4、配置aop管理切入点和通知-->
    <aop:config>
        <!--定义切面,表达式匹配所有的连接点方法-->
        <aop:pointcut id="pointcut" expression="execution(* com.entor.jdbc.service.impl.*.*(..))"/>
        <!--把切面和通知关联上-->
        <aop:advisor advice-ref="advice" pointcut-ref="pointcut"/>
    </aop:config>

aop:advice与aop:advisor区别

aop:advice配置的通知类可以是普通java对象,不实现接口,也不使用继承关系

aop:advisor配置的通知类必须实现通知接口

MethodBeforeAdvice

AfterReturningAdvice

ThrowsAdvice

tx:advice

类型:标签

归属:beans标签

作用:专用于声明事务通知
基本属性:
	id :用于配置aop时指定通知器的id
	transaction-manager :指定事务管理器bean

tx:attributes

类型:标签

归属:tx:advice标签

作用:定义通知属性

tx:method

类型:标签

归属:tx:attribute标签

作用:设置具体的事务属性
说明:通常事务属性会配置多个,包含1个读写的全事务属性,1个只读的查询类事务属性

tx:method属性
在这里插入图片描述

声明式事务(注解)

@Transactional

类型:方法注解,类注解,接口注解

位置:方法定义上方,类定义上方,接口定义上方

作用:设置当前类/接口中所有方法或具体方法开启事务,并指定相关事务属性
@Transactional//等价于<tx:annotation-driven transaction-manager="txManager"/>
(
    readOnly = false,
    timeout = -1,
    isolation = Isolation.DEFAULT,
    rollbackFor = {ArithmeticException.class, IOException.class},
    noRollbackFor = {},
    propagation = Propagation.REQUIRES_NEW
)

tx:annotation-driven

类型:标签

归属:beans标签

作用:开启事务注解驱动,并指定对应的事务管理器
<tx:annotation-driven transaction-manager="txManager"/>

声明式事务(纯注解驱动)

@EnableTransactionManagement

类型:类注解

位置:Spring注解配置类上方

作用:开启注解驱动,等同XML格式中的注解驱动
@Configuration
@ComponentScan("com.entor")
@PropertySource("classpath:jdbc.properties")
@Import({JDBCConfig.class,MyBatisConfig.class,TransactionManagerConfig.class})
@EnableTransactionManagement
public class SpringConfig {
}
public class TransactionManagerConfig {
    @Bean
    public PlatformTransactionManager getTransactionManager(@Autowired DataSource dataSource){
        return new DataSourceTransactionManager(dataSource);
    }
}
 @Bean("dataSource")
    public DruidDataSource getDataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("oracle.jdbc.driver.OracleDriver");
        ds.setUrl("jdbc:oracle:thin:@localhost:1521:XE");
        ds.setUsername("jsd2101");
        ds.setPassword("jsd2101");
        return ds;
    }

    @Bean
    public DataSourceTransactionManager getTransactionManager(DruidDataSource dataSource){
        return new DataSourceTransactionManager(dataSource);
    }
    @Bean
    public JdbcTemplate getJDBCTemplate(DruidDataSource dataSource){

           return new JdbcTemplate(dataSource);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值