• 了解一下事务的概念


    什么是事务

    事务(Transaction),一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。要么全部执行,要么全部不执行。

    事务的特性

    事务有4个特性,简称ACID。

    • 原子性(Atomicity):一个事务是一个不可分割的工作单位,事务中包括的操作要么都做,要么都不做。
    • 一致性(Consistency):事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
    • 隔离性(Isolation):一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
    • 持久性(Durability):一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

    事务的传播机制

    @Transactional注解的Propagation属性可以指定事务的传播机制。

    public enum Propagation {
    
    	/**
    	 * Support a current transaction, create a new one if none exists.
    	 * Analogous to EJB transaction attribute of the same name.
    	 * <p>This is the default setting of a transaction annotation.
    	 */
    	REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),
    
    	/**
    	 * Support a current transaction, execute non-transactionally if none exists.
    	 * Analogous to EJB transaction attribute of the same name.
    	 * <p>Note: For transaction managers with transaction synchronization,
    	 * PROPAGATION_SUPPORTS is slightly different from no transaction at all,
    	 * as it defines a transaction scope that synchronization will apply for.
    	 * As a consequence, the same resources (JDBC Connection, Hibernate Session, etc)
    	 * will be shared for the entire specified scope. Note that this depends on
    	 * the actual synchronization configuration of the transaction manager.
    	 * @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setTransactionSynchronization
    	 */
    	SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),
    
    	/**
    	 * Support a current transaction, throw an exception if none exists.
    	 * Analogous to EJB transaction attribute of the same name.
    	 */
    	MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),
    
    	/**
    	 * Create a new transaction, and suspend the current transaction if one exists.
    	 * Analogous to the EJB transaction attribute of the same name.
    	 * <p><b>NOTE:</b> Actual transaction suspension will not work out-of-the-box
    	 * on all transaction managers. This in particular applies to
    	 * {@link org.springframework.transaction.jta.JtaTransactionManager},
    	 * which requires the {@code javax.transaction.TransactionManager} to be
    	 * made available to it (which is server-specific in standard Java EE).
    	 * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
    	 */
    	REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),
    
    	/**
    	 * Execute non-transactionally, suspend the current transaction if one exists.
    	 * Analogous to EJB transaction attribute of the same name.
    	 * <p><b>NOTE:</b> Actual transaction suspension will not work out-of-the-box
    	 * on all transaction managers. This in particular applies to
    	 * {@link org.springframework.transaction.jta.JtaTransactionManager},
    	 * which requires the {@code javax.transaction.TransactionManager} to be
    	 * made available to it (which is server-specific in standard Java EE).
    	 * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
    	 */
    	NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),
    
    	/**
    	 * Execute non-transactionally, throw an exception if a transaction exists.
    	 * Analogous to EJB transaction attribute of the same name.
    	 */
    	NEVER(TransactionDefinition.PROPAGATION_NEVER),
    
    	/**
    	 * Execute within a nested transaction if a current transaction exists,
    	 * behave like PROPAGATION_REQUIRED else. There is no analogous feature in EJB.
    	 * <p>Note: Actual creation of a nested transaction will only work on specific
    	 * transaction managers. Out of the box, this only applies to the JDBC
    	 * DataSourceTransactionManager when working on a JDBC 3.0 driver.
    	 * Some JTA providers might support nested transactions as well.
    	 * @see org.springframework.jdbc.datasource.DataSourceTransactionManager
    	 */
    	NESTED(TransactionDefinition.PROPAGATION_NESTED);
    
    
    	private final int value;
    
    
    	Propagation(int value) {
    		this.value = value;
    	}
    
    	public int value() {
    		return this.value;
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    REQUIRED当前存在事务,则加入这个事务;当前不存事务,则新建一个事务;
    SUPPORTS当前存在事务,则加入这个事务;当前不存在事务,则以非事务的方式执行;
    MANDATORY当前存在事务,则加入这个事务;当前不存事务,则抛出异常;
    REQUIRES_NEW创建一个新事务,如果当前存在事务,则暂停当前事务;
    NOT_SUPPORTED以非事务方式执行,如果存在则暂停当前事务;
    NEVER以非事务方式执行,如果存在事务则抛出异常。
    NESTED如果当前事务存在,则在嵌套事务中执行,类似于PROPAGATION_REQUIRED;

    脏读、幻读、不可重复读

    • 脏读

    数据库有个amount的字段值100
    1、事务A修改字段值为200,尚未未提交;
    2、事务B读取了事务A修改的字段值200;
    3、事务A发生了回滚,amount还原为100;
    事务B读到200就是脏读。

    • 幻读

    1、事务A读取数据库表age=20的10条记录,并进行更新;
    2、事务B添加1条age = 20 记录;
    3、事务A再次读取age = 20的记录数为11条。
    前后两次读取的记录数不一样,产生了幻读。

    • 不可重复读

    数据库有个amount的字段值100
    1、事务A读取amount = 100;
    2、事务B修改amount的值为200;
    3、事务A再次读取amount = 200;
    事务A前后两次读取的字段值不一样,不可重复读。

    事务的隔离级别

    避免上面出现的几种情况,在标准SQL规范中,定义了4个事务隔离级别,不同的隔离级别对事务的处理不同。
    读未提交(READ_UNCOMMITTED)
    允许在提交该行中的任何更改之前由另一个事务读取由一个事务更改的行(“脏读”)。如果回滚任何更改,则第二个事务将检索到无效行。

    读已提交(READ_COMMITTED)
    不允许脏读,可能发生不可重复读取和幻读。禁止事务读取其中包含未提交更改的行。

    可重复读(REPEATABLE_READ)
    不允许脏读和不可重复读,可能发生幻读。禁止一个事务读取其中未提交更改的行,同时也禁止一个事务读取一行,第二个事务更改该行,第一个事务重新读取该行,第二次得到不同值的情况( “不可重复读取”)。

    序列化(SERIALIZABLE)
    不允许防止脏读、不可重复读和幻读。提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,不能并发执行。

  • 相关阅读:
    SpringBoot+Vue项目智能选课系统
    监狱工具管理系统-监狱劳动工具管理系统
    springboot中的一些配置(如端口号的更换)
    python --opencv图像处理轮廓(寻找轮廓、绘制轮廓)详解
    Taro安装及使用
    Spring之Bean的自动装配
    Linux服务器 james邮箱服务器搭建 (附java测试Demo)
    iOS全埋点解决方案-界面预览事件
    Android 和 Kotlin 有什么不一样
    【Linux】Ubuntu安装QQ【教程】
  • 原文地址:https://blog.csdn.net/qq_36700462/article/details/125597778