IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 事务的描述 -> 正文阅读

[大数据]事务的描述

事务

事务

是操作数据库的最小工作单元,为单个逻辑工作单元执行的一系列操作,这些操作作为一个整体一起向系统提交,要么都执行,或都不执行,事务是一组不可在分割的操作集合

一起成功(事务提交),一起失败(事务回滚)

事务的四大特性:(一原持久隔离)

一致性:事务执行后,数据库与其他业务保持一致,无论是成功还是失败。如转账业务,参与转账的两个账号余额之和应该是不变的

原子性:事务操作是不可再分割的原子单位,事务中所有的操作要么执行全部成功,要么全部执行失败。

持久性:一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证通过某种机制恢复数据。

隔离性:隔离性指在并发操作中,不同事物之间应该隔离开来,使每个并发中的事务不会相互干扰。

原生jdbc事务处理

public class DBUtil {
private static String url;
private static String username;
private static String password;

static {
    Properties p = new Properties();
    try {
        p.load(DBUtil.class.getClassLoader().getResourceAsStream("DBConfig.properties"));
    } catch (IOException e) {
        e.printStackTrace();
    }
    String driverName = p.getProperty("driverName");
    url = p.getProperty("url");
    username = p.getProperty("username");
    password = p.getProperty("password");

    try {
        //加载驱动
        Class.forName(driverName);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}

//获取连接对象
public static Connection getConnection() throws SQLException{
    Connection connection = DriverManager.getConnection(url, username, password);
    return  connection;
}

public static void close(Connection connection, Statement statement, ResultSet resultSet){
    if (resultSet != null){
        try {
            resultSet.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    if (statement != null){
        try {
            statement.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    if (connection != null){
        try {
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
 * 知识点:在Java中使用事务
    Connection connection = null;
    PreparedStatement statement = null;
    try {
        connection = DBUtil.getConnection();

        //开启事务(设置不自动管理提交)
        connection.setAutoCommit(false);

        String sql1 = "UPDATE bank SET money=money-200 WHERE id=1;";
        statement = connection.prepareStatement(sql1);
        statement.executeUpdate();

        statement = connection.prepareStatement("UPDATE bw1w12ank SET money=money-200 WHERE id=1;");
        statement.executeUpdate();

        String sql2 = "UPDATE bank SET money=money+200 WHERE id=2;";
        statement = connection.prepareStatement(sql2);
        statement.executeUpdate();

        //提交事务
        connection.commit();

    } catch (SQLException e) {
        System.out.println("SQL异常");
        try {
            //回滚事务
            connection.rollback();
        } catch (SQLException e1) {
            e1.printStackTrace();
        }
    } finally {
    	connection.setAutoCommit(true);
        DBUtil.close(connection,statement,null);
    }

事务的隔离级别情况

脏读

小花读取了小明未提交的新事务,然后小明回滚了,小花就读取了错误的数据(小明的事务在中间回滚了,实际上小花,小明的钱款并未改变)

脏读

不可重复读

一个事务范围内多次查询却返回了不同的数据,这是由于查询间隔,被另一个事务修改并提交了。

不可重复读

幻读

也是不可重复读的特性导致

a事务中有查询和修改两个动作,查询只有一条数据和修改以为也只有一条,但是在同一时间b事务插入了一条数据并提交事务,a事务的修改就修改了两条然后才提交事务。所以再次查询就修改了两条数据产生了幻读

幻读

第一类事务丢失(回滚事务丢失)

小明这个事务取50,然后中途放弃把50又还回去(回滚),这时如花这个事务放了50进去,跟回滚重合如花这个事务就丢失了。

第一类事务丢失

第二类事务丢失(提交覆盖丢失)

小花开个事务放50进去,这时小明也开了个事务放50进去,导致小明覆盖了小花,小花事务丢失,总金额只有150

提交事务覆盖丢失

事务的隔离级别5种

DEFAULT

默认隔离级别,每种数据库支持的事务隔离级别不一样,MySQL默认采用的REPEATABLE_READ隔离级别,Oracle默认采用的READ_COMMITTED隔离级别。

READ_UNCOMMITTED

读未提交,即能够读取到没有被提交的数据,所以很明显这个级别的隔离机制无法解决脏读、不可重复读、幻读中的任何一种,因此很少使用

READ_COMMITED

读已提交,允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。

REPEATABLE_READ

重复读取,即在数据读出来之后加锁,类似"select * from XXX for update",明确数据读取出来就是为了更新用的,所以要加一把锁,防止别人修改它。除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生

SERLALIZABLE

串行化,最高的事务隔离级别,不管多少事务,挨个运行完一个事务的所有子事务之后才可以执行另外一个事务里面的所有子事务,这样就解决了脏读、不可重复读和幻读的问题了,将严重影响程序的性能

spring事务

spring配置事务

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="url" value="${jdbc.url}"/>
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>

</bean>

舍弃

<!--在spring中默认配置 配置jdbcTemplate  一个模板-->
<bean class="org.springframework.jdbc.core.JdbcTemplate">
 <property name="dataSource" ref="dataSource"/>
</bean>
<!--数据源  事务管理器配置-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <!--管理的数据源-->
    <property name="dataSource" ref="dataSource"/>
</bean>

舍弃

<!--在spring中默认配置TransactionTemplate模板 -->
<!--事务管理器模板-->
<bean id="transactionManager" class="org.springframework.transaction.support.TransactionTemplate">
    <!--管理的数据源-->
    <property name="transactionManager" ref="transactionManager"/>
</bean>

舍弃

  <!--基于AspectJ 申明事务xml -->
    <!--配置类型的声明式事务-->
<tx:advice id="tx" transaction-manager="transactionManager">
  <!--增强事务属性的配置-->
        <tx:attributes>
			<!--isolation: DEFAULT,事务的隔离级别
			propagation:事务的传播行为
			read-only:false, 不是只读
			timeout:-1  ,解除死锁
			no-rollback-for:发现哪些异常不会滚
			rollback-for:发现哪些异常回滚事务
			-->
            <!--            get* => 其中*表示匹配任意字符串,这里表示的是凡是以get开始的方法-->
<tx:method name="get*" propagation="REQUIRED" isolation="READ_COMMITTED"/>-->
</tx:advice>
<aop:config>
        <!--定义切点  哪些类和哪些方法应用增强-->
<aop:pointcut id="pc" expression="execution(* com.qf.ssm.service..*(..))"/>
        <!--安装事物通知  定义切面-->
<aop:advisor advice-ref="tx" pointcut-ref="pc" />
    </aop:config>-->
<!--开启事务注解驱动-->
<tx:annotation-driven />
<!--扫描service层-->
<context:component-scan base-package="com.qf.ssm.service" />
@Configuration
//开启注解事务
@EnableTransactionManagement
public class AppConfig {
    
      //事务管理器 多数据源
    @Bean
    public PlatformTransactionManager platformTransactionManager(){
        return new DataSourceTransactionManager(dataSource);
    }
}

spring事务的7种传播特性

作用在方法上传播特性

保证同一个事务中
PROPAGATION_REQUIRED 支持当前事务,如果不存在 就新建一个(默认)
PROPAGATION_SUPPORTS 支持当前事务,如果不存在,就不使用事务
PROPAGATION_MANDATORY 支持当前事务,如果不存在,抛出异常
保证没有在同一个事务中
PROPAGATION_REQUIRES_NEW 如果有事务存在,挂起当前事务,创建一个新的事务
PROPAGATION_NOT_SUPPORTED 以非事务方式运行,如果有事务存在,挂起当前事务
PROPAGATION_NEVER 以非事务方式运行,如果有事务存在,抛出异常
PROPAGATION_NESTED 没有事务就新建一个,如果当前事务存在,则嵌套事务执行

Hibenate不支持嵌套事务PROPAGATION_NESTED,mybatis和jdbc支持嵌套事务

持当前事务,如果不存在,抛出异常
保证没有在同一个事务中
PROPAGATION_REQUIRES_NEW 如果有事务存在,挂起当前事务,创建一个新的事务
PROPAGATION_NOT_SUPPORTED 以非事务方式运行,如果有事务存在,挂起当前事务
PROPAGATION_NEVER 以非事务方式运行,如果有事务存在,抛出异常
PROPAGATION_NESTED 没有事务就新建一个,如果当前事务存在,则嵌套事务执行

Hibenate不支持嵌套事务PROPAGATION_NESTED,mybatis和jdbc支持嵌套事务

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-12-24 18:32:57  更:2021-12-24 18:34:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:28:38-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码