spring事务管理复习
发布日期:2021-06-28 20:50:53 浏览次数:2 分类:技术文章

本文共 4581 字,大约阅读时间需要 15 分钟。

1、  事务回顾

事务指的的是逻辑上一组操作,这组要么全都成功,要么全都失败!

事务四大特性

原子性:不可分割,要么都发生,要么都不发生;

一致性:事务的执行前后数据要保持一致;

隔离性:多个用户操作,相互之间事务不能干扰,通过事务的隔离级别做到;

持久性:事务一旦提交,那么数据就会保存持久化了。

 

2、  Spring事务管理的api

Spring事务管理高层抽象的主要包括3个接口

PlatformTransactionManager:事务管理器

TransactionDefinition事务定义信息(隔离,传播,超时,只读)

TransactionStatus事务具体运行状态(是否提交,保存点,是否新事务)

 

Spring为不同的持久层框架提供了不同PlatformTransactionManager接口实现

例如在xml中配置如下:

<!-- 配置事务管理器,注意这里的dataSource和SqlSessionFactoryBean的dataSource要一致,不然事务就没有作用了 -->

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

           <property name="dataSource"ref="dataSource" />

</bean>

 

TransactionDefinition接口指定

· 事务隔离:(4种)当前事务和其它事务的隔离的程度。例如,这个事务能否看到其他事务未提交的写数据?

· 事务传播:(7种)通常在一个事务中执行的所有代码都会在这个事务中运行。但是,如果一个事务上下文已经存在,有几个选项可以指定一个事务性方法的执行行为:例如,简单地在现有的事务中继续运行(大多数情况);或者挂起现有事务,创建一个新的事务。Spring提供EJB CMT中常见的事务传播选项

· 事务超时:事务在超时前能运行多久(自动被底层的事务基础设施回滚)。

· 只读状态:只读事务不修改任何数据。只读事务在某些情况下(例如当使用Hibernate时),是一种非常有用的优化

脏读:一个事务读取到另一事务还没有提交的数据,如果这些数据被回滚,那读取到的数据就是无效的!

不可重复读:同一事务

幻读:

Default使用的就是数据库对应的隔离级别:

Mysql默认采用的是Repeatable_read隔离级别

Oracle默认采用的是Read_Committed隔离级别        

 

事务的传播行为7种

事务一般都添加到业务层,

事务的传播行为解决的问题:业务层方法之间的相互调用的问题!

假设有业务层有两个方法:AAA(), BBB()

PROPAGATION_NESTED:AAA()执行完开始调用BBB(),设置保存点,如果BBB成功,一起提交,如果bbb失败,那么可以设置回滚到保存点,或者回滚到最开始。

 

TransactionStatus接口

案例:

环境准备:

Mysql:

CREATE TABLE `account` (

  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL,
  `money` double DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8

 

代码:spring/transaction/

3、  Spring编程式的事务管理http://blog.sina.com.cn/s/blog_7ffb8dd501014dzh.html

Spring为了简化编程。提供了TransactionTemplate

在本案例中

在AccountSevice中使用TransactionTemplate

TransactionTemplate依赖DataSourceTransactionManager

DataSourceTransactionManager依赖DataSource进行构造

 

4、  Spring声明式的事务管理,http://blog.sina.com.cn/s/blog_7ffb8dd501014dzx.html

有多种方式:

实现方式一 使用原始TransactionProxyFactoryBean

    <!-- 引入外部资源 -->

    <context:property-placeholderlocation="classpath:c3p0.properties"/>

    

    

    <!-- 配置c3p0的连接池 -->

    <bean id="dataSource"class="com.mchange.v2.c3p0.ComboPooledDataSource">

           <propertyname="driverClass" value="${c3p0.driverClass}" />

           <propertyname="jdbcUrl" value="${c3p0.jdbcUrl}" />

           <property name="user"value="${c3p0.user}" />

           <propertyname="password" value="${c3p0.password}" />

    </bean>

    

    <!-- 配置dao层的类 -->

    <bean id="accountDao"class="com.sanshi.spring.transaction.service.AccountDaoImp">

           <propertyname="dataSource" ref="dataSource"/>

    </bean>

    

    <!-- 配置业务层类 -->

    <bean id="accountService"class="com.sanshi.spring.transaction.service.AccountServiceImp">

                 <propertyname="accountDao" ref="accountDao" />

    </bean>

    

    <!-- 配置事务管理器 PlatformTransactionManager的一个实现。用于jdbc,c3p0 ,而hibernate用另外一个实现-->

    <bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

          <propertyname="dataSource" ref="dataSource"/>

         </bean>

        

         <!--配置业务层的代理 -->

         <beanid="accountServiceProxy"class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

            <!-- 配置目标对象 -->

            <property name="target"ref="accountService" />

            <!-- 注入事务管理器 -->

            <propertyname="transactionManager" ref="transactionManager"/>

            <!-- 配置事务相关属性 -->

            <propertyname="transactionAttributes">

                        <props>

                          <!-- prop中的格式

                           * PROPAGATION : 事务的传播行为

                           * ISOLATION       : 事务的隔离级别

                           * readOnly   : 只读(不能进行更新和添加操作)

                           * -Exception : 发生哪些异常回滚事务

                           * +Exception : 发生哪些异常不回滚事务

                           -->

                           <propkey="tansfer*">PROPAGATION_REQUIRED,+java.lang.ArithmeticException</prop>

                        </props>

            </property>

         </bean>

然后在使用的时候,使用增强的代理对象

         /**

          * 必须注入代理类: 因为代理类对应业务类进行了增强

          */

         @Resource(name="accountServiceProxy")

         privateAccountService accountService;

 

实现方式二 基于aspectJ的xml配置。需要因为对应jar包

<!-- 配置事务的通知-->

         <tx:adviceid="txAdvice" transaction-manager="transactionManager">

                   <tx:attributes>

                       <!--

                         propagation: 事务的传播行为

                         isolation:      事务的隔离级别

                         read-only:   只读

                         rollback-for: 发生哪些异常时回滚

                         no-rollback-for:发生哪些异常异常不回滚

                        -->

                            <tx:methodname="tansfer*" propagation="REQUIRED"rollback-for="java.lang.ArithmeticException"/>

                   </tx:attributes>

         </tx:advice>

        

         <!--配置切面 -->

         <aop:config>

                   <!--配置切入点

                   execution(modifiers-pattern?ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)throws-pattern?)

                            第一个是修饰符(modifiers-pattern)

                            第二个是返回值(ret-type-pattern)

                            第三个方法的包名(declaring-type-pattern)

                            第四个是方法名(name-pattern)

                            第五个方法参数(param-pattern)

                            第六个抛出的异常类型(throws-pattern)

                            其中 ?对应的值 可以省略

                    -->

                   <aop:pointcutexpression="execution(*com.sanshi.spring.transaction.dao.AccountService+.*(..))"id="pointcut1"/>

                   <!--配置 切面

                     在pointcut1切入点上。用txAdvice来增强

                   -->

                   <aop:advisoradvice-ref="txAdvice" pointcut-ref="pointcut1" />

         </aop:config>

使用的时候还是使用原对象,不需要改变什么

 

实现方式三 基于注解方式

<!-- 开启注解事务 -->

 <tx:annotation-driventransaction-manager="transactionManager"/>

在业务层需要使用事务的类或者方法上面加上注解就可以了。

 

转载地址:https://blog.csdn.net/yangleiGJ/article/details/53095565 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:大表添加字段、索引
下一篇:java多线程并发

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.219.124.196]2024年04月12日 00时44分10秒