Spring AOP--声明式事务

1.Spring支持两种事务的声明方式

a.编程式事务管理:通过Transaction Template手动管理事务,实际应用中很少使用。
b.使用xml配置声明式事务:实际中用的很多因为代码侵入性最小,而且是通过AOP实现的。

(这里我们讲解一下声明式事务)

2.实现声明式事务管理的方式

a.基于< tx> 和< aop>命名空间的声明式事务管理:其与Spring AOP 结合紧密,可以充分利用切点表达式的强大支持,使得管理事务更加灵活。
b.基于 @Transactional 的注解方式:此方式将声明式事务管理简化到了极致。操作简单,功能不逊a方式。
(其他两种方法因长期不使用本次不再介绍)

3.XML配置方式

Spring封装了事务管理的代码,事务的操作一般有三步,打开事务,提交事务,回滚事务。为了让我们更好的管理事务的对象,spring为我们提供了一个接口PlatfromTransactionManager,它有很多实现类,我们就使用其中的一个实现类
DataSourceTransactionManager,因为使用jdbc或者ibatis进行数据持久化时使用。
配置xml文件:
a.将两个bean建立连接一个是jdbc一个是dao层类

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource" />
</bean>
<bean id="teacherDao" class="com.lanou3g.spring.transaction.dao.TeacherDaoImpl">
    <property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>

b.配置数据源(并引入外部properties文件)

<context:property-placeholder location="classpath:jdbc.properties" />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="url" value="${jdbc.url}" />
    <property name="driverClassName" value="${jdbc.driver}" />
    <property name="username" value="${jdbc.user}" />
    <property name="password" value="${jdbc.password}" />
    <property name="connectionProperties">
        <props>
            <prop key="characterEncoding">${jdbc.characterEncoding}</prop>
        </props>
    </property>
</bean>

c.初始化事务管理器

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

d.配置事务AOP通知

<tx:advice id="txAdvice" transaction-manager="txManager">   
 <tx:attributes>
 <tx:method name="insert*" rollback-for="ArithmeticException" /> 
 <tx:method name="query*" isolation="READ_COMMITTED" read-only="true" />    </tx:attributes></tx:advice>

e.定义AOP配置

<aop:config>
<aop:pointcut id="all_dao_method" expression="execution(*com.lanou3g.spring.transaction.dao.*.*(..))" /> 
<aop:advisor advice-ref="txAdvice" pointcut-ref="all_dao_method" />
</aop:config>

这样就完成了xml方式配置

4.注解方式配置(此处我们讲解为纯注解方式,混和方式下次分析)

a.先配置切点表达式

扫描二维码关注公众号,回复: 6731808 查看本文章
@Pointcut("execution(* com.xxx.spring.simple.say..*.*(..))")

b.配置连接数据库

@PropertySource("classpath:jdbc.properties")
@Componentpublic class MyDataSource extends DriverManagerDataSource{ 
 public MyDataSource(@Value("${jdbc.driver}") String driver, @Value("${jdbc.url}") String url, @Value("${jdbc.user}") String userName, @Value("${jdbc.password}") String password, @Value("${jdbc.characterEncoding}") String characterEncoding) { 
 super.setDriverClassName(driver); 
 super.setUrl(url);
 super.setUsername(userName);
 super.setPassword(password);
 Properties conProperties = new Properties();
 conProperties.setProperty("characterEncoding", characterEncoding); 
 super.setConnectionProperties(conProperties);
   }
 }

c.在dao层中设置开始事务以及设置属性

@Transactional(rollbackFor = {ArithmeticException.class})
@Transactional(readOnly = true)//事务的属性下面介绍

d.在main方法类中添加开启事务相关注解

@Slf4j
@Configuration
@ComponentScan(basePackages = "com.lanou3g.spring.transaction.annotation")// 开启事务相关注解支持
@EnableTransactionManagement

  此时我们使用的@EnableTransactionManagement这个注解,我们可以使用@Transactional不过属性要在后面直接加上,就此注解配置完成。但是Spring AOP 代理有两个弊端一个是注解方式只能用到public方法上,和自调用问题,所以我们可以将AspectJ 信息添加到 xml 配置信息中,下次再讲解。

5.Spring事务的隔离级别和传播行为

  事务定义接口 TransactionDefinition 中定义了事务描述相关的三类常量:事务隔离级别、事务传播行为、事务默认超时时限,及对它们的操作。
五大隔离级别:
隔离级别说明

  • ISOLATION_DEFAULT这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.
  • ISOLATIONREADUNCOMMITTED这是事务最低的隔离级别,它允许另外一个事务可以看到这个事务未提交的数据。 这种隔离级别会产生脏读,不可重复读和幻像读。
  • ISOLATIONREADCOMMITTED保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。 这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读。
  • ISOLATIONREPEATABLEREAD这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。 它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
  • ISOLATION_SERIALIZABLE这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。 除了防止脏读,不可重复读外,还避免了幻像读。

七大传播行为:

  • PROPAGATION_REQUIRED – 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
  • PROPAGATION_SUPPORTS – 支持当前事务,如果当前没有事务,就以非事务方式执行。
  • PROPAGATION_MANDATORY – 支持当前事务,如果当前没有事务,就抛出异常。
  • PROPAGATION_REQUIRES_NEW – 新建事务,如果当前存在事务,把当前事务挂起。
  • PROPAGATION_NOT_SUPPORTED – 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  • PROPAGATION_NEVER – 以非事务方式执行,如果当前存在事务,则抛出异常。
  • PROPAGATION_NESTED –如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。

6.回滚事务

我们可以在xml中和注解中分别添加完成开始事务介绍一下xml配置
a.回滚特定异常

<tx:advice id="txAdvice" transaction-manager="txManager">
  <tx:attributes>
     <tx:method name="get*" read-only="true" rollback-for="NoProductInStockException"/>
     <tx:method name="*"/>
  </tx:attributes>
</tx:advice>

b.不会滚特定异常

    <tx:attributes>
        <tx:method name="updateStock" no-rollback-for="InstrumentNotFoundException"/>
        <tx:method name="*"/>
    </tx:attributes>
</tx:advice>

至此两种配置方式已经结束,但是关于事务的更多知识还有很多下次分享!

猜你喜欢

转载自blog.csdn.net/dianjishamaoxian/article/details/93136637