广告
返回顶部
首页 > 资讯 > 数据库 >Spring的事务管理
  • 549
分享到

Spring的事务管理

2024-04-02 19:04:59 549人浏览 泡泡鱼
摘要

一、事务的基础知识数据库事务:复杂的事务要分步执行,要么整体生效、要么整体失效。必须满足:原子性、一致性、隔离性、持久性。数据并发问题:脏读:A读取了B未提交的更改数据。    &nbs

一、事务的基础知识

  1. 数据库事务:复杂的事务要分步执行,要么整体生效、要么整体失效。

  2. 必须满足:原子性、一致性、隔离性、持久性。

  3. 数据并发问题:脏读:A读取了B未提交的更改数据。

             不可重复读:A两次读,第二次读到了B已经提交的数据。(行级

             幻读(虚读):A读取B新提交的新增数据。(需添加表级锁)

             第一类丢失更新:A撤销时恢复原数据把B提交的数据覆盖了。

             第二类丢失更新:A提交时覆盖了B已经提交的数据。

  4. 数据库锁机制:一般分为表锁和行锁,按并发来分有共享锁和独占锁。数据库必须在更改的行上施加独占锁;行共享锁、行独占锁、表共享锁、表共享行独占锁、表独占锁。

  5. 事务隔离级别:

Spring的事务管理


6.JDBC对事务的支持


二、ThreadLocal

  1. 概念:ThreadLocal是保存线程本地化的容器,为每个使用该变量的线程分配一个独立的变量副本。

  2. 原理:通过Map来保存每个线程的变量副本,key为线程对象,值为线程的副本。

public class TestNum {  
    // ①通过匿名内部类覆盖ThreadLocal的initialValue()方法,指定初始值  
    private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>() {  
        public Integer initialValue() {  
            return 0;  
        }  
    };  
  
    // ②获取下一个序列值  
    public int getNextNum() {  
        seqNum.set(seqNum.get() + 1);  
        return seqNum.get();  
    }  
  
    public static void main(String[] args) {  
        TestNum sn = new TestNum();  
        // ③ 3个线程共享sn,各自产生序列号  
        TestClient t1 = new TestClient(sn);  
        TestClient t2 = new TestClient(sn);  
        TestClient t3 = new TestClient(sn);  
        t1.start();  
        t2.start();  
        t3.start();  
    }  
  
    private static class TestClient extends Thread {  
        private TestNum sn;  
  
        public TestClient(TestNum sn) {  
            this.sn = sn;  
        }  
  
        public void run() {  
            for (int i = 0; i < 3; i++) {  
                // ④每个线程打出3个序列值  
                System.out.println("thread[" + Thread.currentThread().getName() + "] --> sn["  
                         + sn.getNextNum() + "]");  
            }  
        }  
    }  
}

spring中大部分Bean都可以声明为singleton,故而spring要对这些非线程安全bean采用Threadlocal进行封装,这样有状态的bean就能够以sigleton的方式在多线程中正常工作。spring通过Threadlocal来实现事务管理


三、spring对事务的支持

  1. spring封装了事务模版类TranscationTemplate.


  2. 事务管理主要有3个接口:PlatfORMTransactionManager,TransactionDefinition,TransactionStatus.

TransactionDefinition:用于描述事务的隔离级别、超时时间、等事务属性;

PlatformTransactionManager根据TransactionDefinition提供的事务属性来创建事务;就三个方法getTransaction、commit、rollback;

TransactionStatus描述激活事务的状态;


3.spring把事务管理委托给底层具体的持久化实现框架来完成,为不同的持久化框架提供了不同的PlatformTransactionManager接口的实现类。

<bean id="dataSource"    
      class="org.apache.commons.dbcp.BasicDataSource"
      destroy-method="close"
      p:driverClassName="${jdbc.driverClassName}"
      p:url="${jdbc.url}"
      p:username="${jdbc.username}"
      p:passWord="${jdbc.password}"/>
<bean id="transactionManager"              2)基于数据源的事务管理器
      class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
      p:dataSource-ref="dataSource"/>      3)引用数据源

Hibernate

1)Hibernate配置

<hibernate-configuration>
    <session-factory>
        <!-- 指定连接数据库所用的驱动 -->
        <property name="connection.driver_class">com.Mysql.jdbc.Driver</property>
        <!-- 指定连接数据库的url,其中hibernate是本应用连接的数据库名 -->
        <property name="connection.url">jdbc:mysql://localhost/hibernate_test</property>
        <!-- 指定连接数据库的用户名 -->
        <property name="connection.username">root</property>
        <!-- 指定连接数据库的密码 -->
        <property name="connection.password">cheng</property>
        <!-- 指定连接池里最大连接数 -->
        <property name="hibernate.c3p0.max_size">20</property>
        <!-- 指定连接池里最小连接数 -->
        <property name="hibernate.c3p0.min_size">1</property>
        <!-- 指定连接池里连接的超时时长 -->
        <property name="hibernate.c3p0.timeout">5000</property>
        <!-- 指定连接池里最大缓存多少个Statement对象 -->
        <property name="hibernate.c3p0.max_statements">100</property>
        <property name="hibernate.c3p0.idle_test_period">3000</property>
        <property name="hibernate.c3p0.acquire_increment">2</property>
        <property name="hibernate.c3p0.validate">true</property>
        <!-- 指定数据库方言 -->
        <property name="dialect">org.hibernate.dialect.Mysql5InnoDBDialect</property>
        <!-- 根据需要自动创建数据表 -->
        <property name="hbm2ddl.auto">update</property><!--①-->
        <!-- 显示Hibernate持久化操作所生成的SQL -->
        <property name="show_sql">true</property>
        <!-- 将SQL脚本进行格式化后再输出 -->
        <property name="hibernate.format_sql">true</property>
        <!-- 避免这个错误信息Disabling contextual LOB creation as createClob() method threw error :java.lang.reflect.InvocationTargetException -->
        <property name="hibernate.temp.use_jdbc_metadata_defaults">false</property>
        <!-- 罗列所有持久化类的类名 -->
        <mapping class="com.wechat.entity.po.User"/>
        <mapping class="com.wechat.entity.po.Person"/>
    </session-factory></hibernate-configuration>

hibernate.cfg.xml文件的主要作用就是配置了一个session-factory

  1. 在session-factory中主要通过property配置一些数据库的连接信息,我们知道,spring通常会将这种数据库连接用dataSource来表示,这样一来,hibernate.cfg.xml文件中的所有跟数据库连接的都可以干掉了,直接用spring的dataSource,而dataSource也可以用c3p0、dbcp等。

  2. 在session-factory中通过property除了配置一些数据库的连接信息之外,还有一些hibernate的配置,比如方言、自动创建表机制、格式化sql等,这些信息也需要配置起来。

  3. 还有最关键的一个持久化类所在路径的配置

2)spring的sessionFactroy配置

<!-- 加载配置文件 -->
    <context:property-placeholder location="classpath:jdbc.properties"
        file-encoding="utf-8" ignore-unresolvable="true" />

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan">
            <list>
                <!-- 可以加多个包 -->
                <value>com.wechat.entity.po</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
                <prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>
            </props>
        </property>
    </bean>


四、声明事务

1.基于aop/tx命名空间的配置:spring在Schema的配置中添加了一个tx命名空间,在配置文件中定义事务属性。

<?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:p="http://www.springframework.org/schema/p" 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-4.0.xsd
     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">

    <import resource="classpath:applicationContext-dao.xml"/>

    <!--配置事务管理器-->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
          p:dataSource-ref="dataSource"/>
    <!--使用切点表达式定义目标方法-->
    <aop:config>
        <!--定义切面-->
        <aop:pointcut id="serviceMethod"
                      expression="execution(* com.smart.service.*Forum.*(..))"/>
        <!--引用事务增强-->
        <aop:advisor pointcut-ref="serviceMethod"
                     advice-ref="txAdvice"/>
    </aop:config>
    <!--定义事务增强-->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="get*" read-only="false"/>
            <tx:method name="add*" rollback-for="PessimisticLockingFailureException"/>
            <tx:method name="update*"/>
        </tx:attributes>
    </tx:advice>
    <!--
        1.引入tx命名空间的声明
        2.配置事务管理器
        3.定义事务增强:事务增强一定需要一个事务管理器的支持,<tx:advice>通过transaction-manager属性引用之前定义的事务管理器,默认查找名为transactionManager
                       所以如果事务管理器命名为transactionManager,可以不指定transaction-manager属性.
        4.使用AOP
    -->
    <!--tx:method的属性
        name 就name是必须的属性 与事务属性关联的方法名 get* handle*等自己起的名字
        isolation 事务隔离级别
        timeout 默认为-1 超时时间
        read-only 默认false 事务是否只读
        rollback-for 默认所有运行期间异常都滚回 
        no-rollback-for 默认所有检查型异常都不滚回
    -->

2.使用注解配置声明式事务

1)在xml中配置

<bean id="txManager"
      class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
      p:dataSource-ref="dataSource"/>

<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>
<!--同上,如果名字是transactionManager 可以省略
    proxy-target-class="true"表示spring会通过创建子类来代理业务类
-->

2)在业务类上注解

@Service
@Transactional
public class BbtForum {
    public ForumDao forumDao;

    public TopicDao topicDao;

    public PostDao postDao;
    ...}

3)@Transactional的属性

默认属性:

事务传播行为:PROPAGATION_REQUIRED

事务隔离级别:iOSLATION_DEFAULT

读写事务属性:读/写事务

超时时间:-1

回滚设置:热河运行期异常引发回滚、任何检查型异常不会引发回滚


4)spring要在具体的业务类上使用@Transactional注解


5)在方法处使用注解会覆盖类定义的注解,如果方法需要使用特殊的事务属性,可以在方法上使用注解

@Transactional(readOnly = true)
public Forum getForum(int forumId) {
    return forumDao.getForum(forumId);
}


五、事务的一些注意点

1.使用不同的事务管理器

@Transactional("name")使用名为name的事务管理器


2.事务管理的目的是保证数据操作的事务性(原子性、一致性、隔离性、持久性)脱离了事务,DAO一样可以进行数据操作。


3.事务的传播性

PROPAGATION_REQUIERD:如果当前没有事务就创建一个,有就加进去

PROPAGATION_SUPPORTS:支持当前事务,没有就以非事务方式执行

PROPAGATION_MANDATORY:使用当前事务,没有就抛出异常

PROPAGATION_REQURES_NEW:新建事务,如果当前存在事务,就将其挂起

PROPAGATION_NOT_SUPPORTED:以非事务方式执行,如果当前有就挂起

PROPAGATION_NEVER:以非事务方式执行,如果有就挂起

PROPAGATION_NESTED:嵌套事务

相同线程中进行互相嵌套调用的事务方法工作在相同的事务中,如果在不同线程,则不同线程下事务方法工作在独立的事务中。






您可能感兴趣的文档:

--结束END--

本文标题: Spring的事务管理

本文链接: https://www.lsjlt.com/news/42806.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Spring的事务管理
    一、事务的基础知识数据库事务:复杂的事务要分步执行,要么整体生效、要么整体失效。必须满足:原子性、一致性、隔离性、持久性。数据并发问题:脏读:A读取了B未提交的更改数据。    &nbs...
    99+
    2022-10-18
  • Spring中怎么管理事务
    今天小编给大家分享一下Spring中怎么管理事务的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。什么是事务一个数据库事务是一个...
    99+
    2023-07-02
  • Spring的事务管理你了解吗
    目录1、事务介绍2、事务的四个特性(ACID)3、Spring 事务管理的核心接口4、PlatformTransactionManager 事务管理器5、TransactionSta...
    99+
    2022-11-13
  • spring怎么实现事务管理
    Spring框架提供了多种方式来实现事务管理。下面是几种常见的方式:1. 声明式事务管理:使用Spring的事务管理器和注解或XML...
    99+
    2023-09-28
    spring
  • Spring详细解读事务管理
    目录什么是事务Spring事务配置Spring事务传播行为1. PROPAGATION_REQUIRED2. PROPAGATION_SUPPORTS3. PROPAGATION_R...
    99+
    2022-11-13
  • Spring事务管理详细讲解
    目录事务回顾spring事务操作基于注解声明事务@Transactional注解使用事务传播机制事务隔离级别@Transactional其他属性基于XML 声明式事务完全注解开发说明...
    99+
    2022-11-13
    Spring事务管理 Spring事务原理 Spring事务管理机制
  • spring事务管理的优点有哪些
    1. 原子性:Spring事务管理确保在事务范围内的所有操作要么全部成功要么全部失败,保证数据的一致性。2. 一致性:Spring事...
    99+
    2023-09-29
    spring
  • 如何理解Spring的Hibernate事务管理机制
    如何理解Spring的Hibernate事务管理机制,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。主要讲了Spring 声明式事务让我们从复杂的Hibernate事务处理中...
    99+
    2023-06-17
  • Spring事务管理零基础入门
    目录一、简介二、特性(一原持久隔离)2.1 原子性2.2 一致性(类似能量守恒)2.3 隔离性2.4 持久性三、隔离级别3.1 事务级别(从低到高)3.2 常用数据库默认级别:3.3...
    99+
    2022-11-13
  • 详谈Spring框架之事务管理
    一、编程式事务二、声明式事务1、基于XML的事务1.1 Spring配置文件 <!-- 配置c3p0数据源,只是进行了最简单的配置 --> <bean id="dataSource" class="com.mchange...
    99+
    2023-05-31
    spring 框架 事务管理
  • Spring 事务管理详解及使用
    ✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识...
    99+
    2023-09-02
    spring java mybatis
  • Spring中事务管理的方式有哪些
    Spring中事务管理的方式有以下几种:1. 编程式事务管理:通过编写代码来管理事务,需要手动开启、提交、回滚事务。可以使用`Pla...
    99+
    2023-09-29
    Spring
  • Spring事务管理的使用细则浅析
    目录Spring 事务管理接口1、事务管理器接口 PlatformTransactionManager2、事务定义接口 TransactionDefinitionSpring 事务管...
    99+
    2023-02-27
    Spring事务管理机制 Spring事务管理方式
  • 深入浅析Java中的Spring事务管理
    深入浅析Java中的Spring事务管理?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。环境与版本本文出来之前的一篇文章中的hibernate的相关lib 外Java事务管理之H...
    99+
    2023-05-31
    java spring ava
  • spring学习JdbcTemplate数据库事务管理
    目录spring JdbcTemplate数据库事务管理一、spring 中的事务管理二、spring 事务管理 API三、使用事务管理1. 配置文件2. 类上添加事务注解sprin...
    99+
    2022-11-13
  • Spring事务管理怎么正确使用
    这篇文章主要介绍“Spring事务管理怎么正确使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Spring事务管理怎么正确使用”文章能帮助大家解决问题。事务(Transaction)是访问数据库的...
    99+
    2023-07-05
  • 详细谈谈Spring事务是如何管理的
    目录前言Spring事务抽象PlatformTransactionManager是事务管理器接口常见的事务管理器有以下几种定义事务的一些参数: 7种事务传播特性: 四种事务隔离级别:...
    99+
    2022-11-12
  • Spring系列之事物管理
    目录前言Spring事务抽象Spring之编程式事物声明式事物事物失效的8种情况及解决办法前言 我们都知道Spring给我们提供了很多抽象,比如我们在操作数据库的过程中,它为我们提供...
    99+
    2022-11-12
  • Spring事务管理中的异常回滚是什么
    目录前言问题场景Spring 管理事务的原理MySQL中的事务管理JDBC中的事务管理Spring中的事务管理Spring中的事务接口到底回滚还是不回滚简明答案什么是执行事务的方法什...
    99+
    2023-02-09
    Spring事务管理异常回滚 Spring异常回滚 Spring事务管理中的异常回滚
  • MySQL中Spring管理的事务开启后不提交引起的事故
    1. 前言 了解到一个事故,在MySQL数据库中,使用Spring管理的事务在开启以后没有在操作结束时提交或回滚,使得原有线程在后续执行数据库操作时可能继续使用原有事务,且不会提交,导致对数据库的修改...
    99+
    2023-09-03
    spring mysql java
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作