Spring中的声明式事务介绍

1、声明式事务与编程式事务:
1.1、配置声明式事务:spring的声明式事务是基于通知advice的
此处一般配置业务层(service层)需要事务管理的方法,例如新增、修改、删除的方法

1.2、编程式事务与声明式事务的区别
1、编程式事务是手写事务控制代码
2、声明式事务的代码已经由spring写好,只需要声明那些方法需要进行事务控制和如何进行事务控制就好。
2、spring声明式事务配置:
ApplicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"

       xsi:schemaLocation="
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd"
    default-autowire="byName"
    >
    <!--加载属性文件-->
    <context:property-placeholder location="classpath:db.properties"></context:property-placeholder>

    <!--数据库连接信息-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${dataSources.driver}"></property>
        <property name="url" value="${dataSources.url}"></property>
        <property name="username" value="${dataSources.username}"></property>
        <property name="password" value="${dataSources.password}"></property>
    </bean>

    <!--事务管理器类:包spring-jdbc下的dataSource中的类-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--全局配置了使用byName配置了自动注入,此处默认使用全局配置,可以不用配置property-->
        <!--<property name="dataSource" ref="dataSource"></property>-->
    </bean>
    <tx:advice id="interceptor" transaction-manager="txManager">
        <tx:attributes>
            <!--配置哪些方法需要事务控制 和 如何进行事务控制
                使用<tx:method name=""/>标签配置哪些方法需要事务控制,name=""配置方法名
                在该标签中,关于方法的事务配置有五个较常用属性:read-only=""、isolation=""、no-rollback-for=""、rollback-for=""、propagation=""
            <tx:method name="insert"/>
            <tx:method name="ins*"/>
            <tx:method name="upd*"/>
            <tx:method name="delete*"/>
            <!--补充配置,事务配置只读-->
            <tx:method name="*" read-only="true"/>
        </tx:attributes>
    </tx:advice>
    <!--切点方法配置,此处主要用于事务的配置,可以使用通配符把切点的范围配置的尽可能大-->
    <aop:config>
        <aop:pointcut id="pointCut" expression="execution(* service.Impl.*.*(..))"></aop:pointcut>
        <aop:advisor advice-ref="interceptor" pointcut-ref="pointCut"></aop:advisor>
    </aop:config>
</beans>

注:声明式事务配置在配置文件头部需要添加文件

xmlns:tx="http://www.springframework.org/schema/tx"
 http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd"

业务层代码(接口省略,此出不展示):

package service.Impl;

import model.User;
import service.IUserService;

import java.util.List;

public class UserService implements IUserService {
    @Override
    public User insert(User user) {
        return user;
    }

    public User insUser(User user){
        User u= insert(user); //调用
        return u;
    }

    @Override
    public User updateUser(User user) {
        return null;
    }

    @Override
    public void deleteUserById(int id) {

    }

    @Override
    public List<User> queryAll() {
        return null;
    }
}

数据库属性文件–db.properties:

dataSources.driver=com.mysql.jdbc.Driver
dataSources.url=jdbc:mysql://localhost:3306/mybatis
dataSources.username=root
dataSources.password=root

3、配置事务控制方法标签的属性简介:
配置哪些方法需要事务控制 和 如何进行事务控制
使用<tx:method name=""/>标签配置哪些方法需要事务控制,name="“配置方法名
在该标签中,关于方法的事务配置有五个较常用属性:read-only=”"、isolation=""、no-rollback-for=""、rollback-for=""、propagation=""

3.1、read-only="":取值true/false,是否是只读事务
3.1.1、如果取值true,则事务为只读事务,查询方法建议都是用该属性值,只读事务对数据库优化有一定效果,可以提升性能;
3.1.2、如果取值false, 该值为默认值,事务需要提交事务,主要新增、更新、删除操作需要。

3.2、isolation="":取值DEFAULT、READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ、SERIALIZABLE,事务的隔离级别配置。
在多线程或者并发访问下如何保证访问到的数据具有完整性(隔离性)。
数据库隔离性分析:脏读、不可重复读、幻读
脏读:事务A读取到事务B中未提交的数据,事务B中的数据放生改变,事务A中读取到的数据可能和数据苦衷的数据不一致,此时认为数据是
脏数据,读取数据的过程叫做脏读。
不可重复读:主要针对的是更新操作,针对的是某一条数据或者某一条数据中的某列数据,两次读取在同一个事务中,当事务A第一次读取数据后,
事务B对事务A读取的数据进行了修改,事务A再次读取的数据与第一次读取的数据不一致,该过程叫做不可重复去。
幻读:幻读主要针对的是新增或者删除操作,两次读取在两个事务中,当事务A查询出数据,事务B在此时新增了一条数据,事务A中读取的数据
与数据中的数据就不一致了,该过程叫做幻读。
DEFAULT:默认值,该值的意义是要底层的数据库判断具体要执行什么隔离级别;
READ_UNCOMMITTED:可能读取到未提交的数据,可能出现脏读、不可重复读、幻读;此隔离级别效率较高
READ_COMMITTED:只能读取到其他事务已经提交的数据,可以防止脏读,但是可能出现不可重复读和幻读。
REPEATABLE_READ:读取的数据添加了锁,因此可以防止脏读、不可重复读,但是可能出现幻读。
SERIALIZABLE:队列曹组偶,对整个表添加了锁,因此在一个事务操作表数据时,另外的事务只能等待该事务完成才能操作表中数据,
此级别是最安全的,但是也是效率最低的。

3.3、propagation="":取值REQUIRED(默认值)、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER、NESTED,控制事务传播行为
当一个具有事务控制的方法被另外一个有事务控制的方法调用,应该如何管理事务(新建事务、在事务中执行,将事务挂起、报异常)
REQUIRED**(默认值)**:如果当前有事务就在事务中执行,如果当前没有事务就新建一个事务。
SUPPORTS:如果当前有事务就在事务中执行,如果当前没有事务就在非事务的状态下执行;
MANDATORY:此值表示必须在事务中执行,如果有事务就在当前事务中执行,如果没有就会报异常;
REQUIRES_NEW:也是必须要在事务中执行,如果当前有事就将当前事务挂起,新建事务执行,如果当前没有事务就会新建事务;
NOT_SUPPORTED:必须在非事务状态下执行,如果当前没有事务就正常执行,如果当前有事务,会将事务挂起;
NEVER:必须在非事务状态下执行,如果当前没有事务正常执行,如果当前有事务就会报错;
NESTED:必须在是事务状态执行,如果当前没有事务就创建一个事务,如果当前有事务就会创建一个嵌套事务。
**3.4、rollback-for="":**值是异常的全限定类名,例如:java.lang.Exception,表示当出现哪类异常时会进行回滚,需要注意的是,当有手动写
抛出异常时,此处一定要进行异常配置。
3.5、no-rollback-for="":取值与上述一致,表示当出现什么异常不必回滚操作

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值