Spring-事务操作

目录

一、事务的概念

二、基于注解方式实现事务管理

2.1 事务传播行为

2.2 事务隔离级别

2.3 其他参数

2.4  完全注解声明式事务管理

三、基于xml配置文件实现事务管理


一、事务的概念

        事务是数据库操作最基本单元,逻辑上一组操作,要么都成功,如果有一个操作失败,则所有操作都失效(回滚)。

        事务的四个特性(ACID)

        (1)原子性

        一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。

        (2)一致性

        在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则

        (3)隔离性

        数据库允许多个并发事务同时对其数据进行读写修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。

        (4)持久性

        事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

         事务操作

        一般将事务添加到 JavaEE 三层结构里面 Service 层(业务逻辑层),

        有两种操作方式:

        编程式事务管理声明式事务管理(使用,底层使用 AOP 原理),声明式事务管理又分为两种方式:

        (1)基于注解方式(使用)

        (2)基于 xml 配置文件方式

         事务管理的API

        提供一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类

        PlatformTransactionManager 接口 -> DataSouceTransactionManager实现类(针对jdbc)

二、基于注解方式实现事务管理

        1、在 spring 配置文件配置事务管理器开启事务注解

<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:aop="http://www.springframework.org/schema/aop" 
     xmlns:tx="http://www.springframework.org/schema/tx" 
     xsi:schemaLocation="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.xsd 
     http://www.springframework.org/schema/aop 
     http://www.springframework.org/schema/aop/spring-aop.xsd 
     http://www.springframework.org/schema/tx 
     http://www.springframework.org/schema/tx/spring-tx.xsd">

<!-- 数据库连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          destroy-method="close">
        <property name="url" value="jdbc:mysql:///user_db" />
        <property name="username" value="root" />
        <property name="password" value="root" />
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    </bean>

<!--创建事务管理器-->
<bean id="transactionManager" 
     class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
     <!--注入数据源-->
     <property name="dataSource" ref="dataSource"></property>
</bean>

<!--开启事务注解-->
<tx:annotation-driven transactionmanager="transactionManager"></tx:annotation-driven>

         2.在 service 上面(或者 service 类里面方法上面)添加事务注解

        (1)@Transactional,这个注解添加到类上面,也可以添加方法上面

        (2)如果把这个注解添加上面,这个里面所有的方法都添加事务

        (3)如果把这个注解添加方法上面,为这个方法添加事务

@Service
@Transactional
public class UserService {
... ...
}

         @Transactional注解里面可以配置事务相关参数

2.1 事务传播行为

        事务传播行为(propagation behavior)指的就是当一个事务方法另一个事务方法调用时,这个事务方法应该如何进行。 
        例如:methodA事务方法调用methodB事务方法时,methodB是继续在调用者methodA的事务中运行呢,还是为自己开启一个新事务运行,这就是由methodB的事务传播行为决定的。

        事务传播行为是Spring框架独有的事务增强特性.

        Spring定义了七种传播行为

        我们将举例说明,以两个方法A、B为例,标注了A的事务传播行为:

事务传播行为类型说明
PROPAGATION_REQUIRED

        如果当前没有事务,就新建一个事务,如果已经存在一个事务中,就加入到这个事务中。这是最常见的选择。

        单独执行A时,开启一个事务T1;B调用了A且B已经存在于事务T2时,就将A加入到T2中。

PROPAGATION_SUPPORTS

        支持当前事务,如果当前没有事务,就以非事务方式执行。也就是说,该模式是否支持事务,看调用它的方法是否有事务支持。

        单纯调用A时,A是按非事务执行的;当B调用A且B存在于事务T1时,A就加入T1。

PROPAGATION_MANDATORY

        支持当前的事务,如果当前没有事务,就抛出异常。

        单独调用A时,因为i它不在事务中,会抛异常;当B调用A且B存在于事务T1时,A就加入T1。

PROPAGATION_REQUIRES_NEW

        新建一个事务,如果当前存在事务,把当前事务挂起。

        B已经存在于事务T2,B调用了A,则新建一个事务T1来执行A,T2暂时挂起。T1执行完再执行T2(T1、T2毫不相干)

PROPAGATION_NOT_SUPPORTED

        以非事务方式执行,如果当前存在事务,就把当前事务挂起。

        B已经存在于事务T2,若B调用了A,则不新建新事务,T2暂时挂起。A执行完再执行T2

PROPAGATION_NEVER

        以非事务方式执行,如果当前存在事务,则抛出异常。

        B已经存在于事务T2,若B调用了A,则抛异常

PROPAGATION_NESTED

        如果当前没有事务,就新建一个事务。如果当前存在事务,则在嵌套事务内执行。

        单独执行A时,开启一个事务T1;B调用了A且B已经存在于事务T2时,就将A所在事务T1嵌套到T2中。

        所谓嵌套事务,大意就是外围事务回滚,内嵌事务一定回滚,而内嵌事务可以单独回滚而不影响外围主事务和其他子事务。

         示例:

@Service
@Transactional(propagation=Propagation.REQUIRED)
public class UserService{
    ... ...
}

2.2 事务隔离级别

        三个读问题:

        1.脏读        一个未提交事务读取到另一个未提交事务修改后数据

        2.不可重复读    一个未提交事务读取到另一已提交事务修改后数据    

        3.幻读        一个未提交事务读取到另一已提交事务添加的新数据

        几种隔离级别:

               示例:

@Service
@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.REPETABLE_READ)
public class UserService{
    ... ...
}

2.3 其他参数

        timeout:超时时间

        (1)事务需要在一定时间内进行提交,如果不提交进行回滚

        (2)默认值是 -1 ,设置时间以秒单位进行计算

        readOnly:是否只读

        (1)读:查询操作,写:添加修改删除操作

        (2)readOnly 默认值 false,表示可以查询,可以添加修改删除操作

        (3)设置 readOnly 值是 true,设置成 true 之后,只能查询 6

        rollbackFor:回滚         -设置出现哪些异常进行事务回滚

        noRollbackFor:不回滚         -设置出现哪些异常不进行事务回滚

2.4  完全注解声明式事务管理

创建配置类,使用配置类替代 xml 配置文件
@Configuration //配置类
@ComponentScan(basePackages = "com.atguigu") //组件扫描
@EnableTransactionManagement //开启事务
public class TxConfig {

 //创建数据库连接池
 @Bean
 public DruidDataSource getDruidDataSource() {
     DruidDataSource dataSource = new DruidDataSource();
     dataSource.setDriverClassName("com.mysql.jdbc.Driver");
     dataSource.setUrl("jdbc:mysql:///user_db");
     dataSource.setUsername("root");
     dataSource.setPassword("root");
     return dataSource;
 }

 //创建 JdbcTemplate 对象(可选)
 @Bean
 public JdbcTemplate getJdbcTemplate(DataSource dataSource) {
     //到 ioc 容器中根据类型找到 dataSource
     JdbcTemplate jdbcTemplate = new JdbcTemplate();
     //注入 dataSource
     jdbcTemplate.setDataSource(dataSource);
    return jdbcTemplate;
}

 //创建事务管理器
 @Bean
 public DataSourceTransactionManager 
 getDataSourceTransactionManager(DataSource dataSource) {
     DataSourceTransactionManager transactionManager = new 
     DataSourceTransactionManager();
     transactionManager.setDataSource(dataSource);
     return transactionManager;
 }
}

三、基于xml配置文件实现事务管理

        在 spring 配置文件中进行配置

                第一步 配置事务管理器

                第二步 配置通知

                第三步 配置切入点切面

<!--1 创建事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 <!--注入数据源-->
     <property name="dataSource" ref="dataSource"></property>
</bean>

<!--2 配置通知-->
<tx:advice id="txadvice">
     <!--配置事务参数-->
     <tx:attributes>
         <!--指定哪种规则的方法上面添加事务-->
         <tx:method name="accountMoney" propagation="REQUIRED"/>
     <!--<tx:method name="account*"/>-->
     </tx:attributes>
</tx:advice>

<!--3 配置切入点和切面-->
<aop:config>
     <!--配置切入点-->
     <aop:pointcut id="pt" expression="execution(*com.spring5.service.UserService.*(..))"/>
 <!--配置切面-->
     <aop:advisor advice-ref="txadvice" pointcut-ref="pt"/>
</aop:config>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值