数据库事务管理与springboot使用事务的方式

事务定义(Transactional)
  • 把某个逻辑单元内对数据库的一系列CRUD操作称之为事务。

例如:网购这个逻辑单元里创建订单,减库存,提交订单等一些列操作称之为事务。

事务管理
  • 事务提交: 事务提交后,数据库将永久更新,相关数据将因之改变,所以提交前要慎重。
  • 事务回滚: 对于不确定因素造成业务流程不能如愿执行时,可以执行回滚。

遵守ACID原则的逻辑单元才能成为事务,进行事务管理。

  • 原子性(Atomicity)

该事务内所有操作,要么都生效,要么都回滚,即不生效。

  • 一致性(Consistency)

进行一些列逻辑相关的数据库操作后,数据从一致状态变成另一种一致状态,要符合现实中业务的逻辑要求。比如A和B相互转账,不管经过如何复杂的转账过程,A和B加起来的余额应该保持不变,期间不存在充值过程。

  • 隔离性(Isolation)

事务级别从低到高为 READ_UNCOMMITTED,READ_COMMITTED,REPEATABLE_READ,SERIALIZABLE
事务并发时可能出现 dirty-read(脏读) non-repeatable-read(不可重复读), phantom-read(幻读) 三种现象.
1.当 Isolation=READ_UNCOMMITTED,则 A事务修改一条记录,还没提交,B事务读取该条记录时,读取了A还没提交的修改内容,如果A最后回滚事务,则B读取了无效数据,即脏读。
2. 当Isolation = READ_COMMITTED.仅避免了脏读。当A事务读取一条记录后,B事务修改了该记录,然后A事务再次读取该记录,前后两次读取的内容可能就不一样了,给人感觉就是不可重复读,误导A事务的后续逻辑。
3. 当Isolation = REPEATABLE_READ ,则避免了脏读和不可重复读,即支持可重复读。但是当A 事务按条件T进行查询时,B事务进行了新增记录并满足条件T,接着A事务再按条件T进行查询,就会多出一条记录,该记录称为幻象记录。同样对A事务的前后逻辑造成不可控影响。
4. 当 Isolation = SERIALIZABLE 时,三种并发造成的问题均被避免了。

// 存在这几种隔离级别的设置,控制并发事务之间的影响程度,来避免一些并发造成的问题,其实现原理时不同程度的同步机制(锁),那么必定是牺牲性能来保证事务的一致性。

  • 持久性(Durability)

已提交的事务,所作修改已经持久化到硬盘,数据库重启将读取持久化的内容。

springboot使用注解开启事务管理

@Transaction配置在@service里操作数据库的类或public方法上,方法上的注解配置会覆盖类上的配置

    /**
    * 抛出任何异常,均回滚事务。
    */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public BudResultDTO addRole(RolePost post) throw DAOException,NotPermitException{
    return null;
    }
    /**
    * 抛出 NotPermitException,
    * rollbackFor 支持数组 {DAOException.class,NotPermitException.class}
    */
    @Transactional(rollbackFor = NotPermitException.class)
    @Override
    public BudResultDTO addRole(RolePost post) throw DAOException,NotPermitException{
    return null;
    }
    / 其他属性,诸如
   // transactionManager 自定义事务管理器,需要实现org.springframework.transaction.PlatformTransactionManager
   // isolation 设置隔离级别,默认-1 ,mysql 默认 repeatable-read ,oracle 默认 read-commited.
   // timeout 设置事务超时,默认-1
   // readOnly 默认 false
   // noRollbackFor  与 rollbackFor相对
 事务的隔离性 ,事物冒泡机制,事务超时设置
/**
/*Interface that defines Spring-compliant transaction properties.                 /*Based on the propagation behavior definitions analogous to EJB CMT /*attributes.
/*  
public interface TransactionDefinition {

	/**
	 * Support a current transaction; create a new one if none exists.
	 * Analogous to the EJB transaction attribute of the same name.
	 * <p>This is typically the default setting of a transaction definition,
	 * and typically defines a transaction synchronization scope.
	 */
	int PROPAGATION_REQUIRED = 0;

	/**
	 * Support a current transaction; execute non-transactionally if none exists.
	 * Analogous to the EJB transaction attribute of the same name.
	 * <p><b>NOTE:</b> For transaction managers with transaction synchronization,
	 * {@code PROPAGATION_SUPPORTS} is slightly different from no transaction
	 * at all, as it defines a transaction scope that synchronization might apply to.
	 * As a consequence, the same resources (a JDBC {@code Connection}, a
	 * Hibernate {@code Session}, etc) will be shared for the entire specified
	 * scope. Note that the exact behavior depends on the actual synchronization
	 * configuration of the transaction manager!
	 * <p>In general, use {@code PROPAGATION_SUPPORTS} with care! In particular, do
	 * not rely on {@code PROPAGATION_REQUIRED} or {@code PROPAGATION_REQUIRES_NEW}
	 * <i>within</i> a {@code PROPAGATION_SUPPORTS} scope (which may lead to
	 * synchronization conflicts at runtime). If such nesting is unavoidable, make sure
	 * to configure your transaction manager appropriately (typically switching to
	 * "synchronization on actual transaction").
	 * @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setTransactionSynchronization
	 * @see org.springframework.transaction.support.AbstractPlatformTransactionManager#SYNCHRONIZATION_ON_ACTUAL_TRANSACTION
	 */
	int PROPAGATION_SUPPORTS = 1;

	/**
	 * Support a current transaction; throw an exception if no current transaction
	 * exists. Analogous to the EJB transaction attribute of the same name.
	 * <p>Note that transaction synchronization within a {@code PROPAGATION_MANDATORY}
	 * scope will always be driven by the surrounding transaction.
	 */
	int PROPAGATION_MANDATORY = 2;

	/**
	 * Create a new transaction, suspending 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 it to it (which is server-specific in standard Java EE).
	 * <p>A {@code PROPAGATION_REQUIRES_NEW} scope always defines its own
	 * transaction synchronizations. Existing synchronizations will be suspended
	 * and resumed appropriately.
	 * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
	 */
	int PROPAGATION_REQUIRES_NEW = 3;

	/**
	 * Do not support a current transaction; rather always execute non-transactionally.
	 * 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 it to it (which is server-specific in standard Java EE).
	 * <p>Note that transaction synchronization is <i>not</i> available within a
	 * {@code PROPAGATION_NOT_SUPPORTED} scope. Existing synchronizations
	 * will be suspended and resumed appropriately.
	 * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
	 */
	int PROPAGATION_NOT_SUPPORTED = 4;

	/**
	 * Do not support a current transaction; throw an exception if a current transaction
	 * exists. Analogous to the EJB transaction attribute of the same name.
	 * <p>Note that transaction synchronization is <i>not</i> available within a
	 * {@code PROPAGATION_NEVER} scope.
	 */
	int PROPAGATION_NEVER = 5;

	/**
	 * Execute within a nested transaction if a current transaction exists,
	 * behave like {@link #PROPAGATION_REQUIRED} otherwise. There is no
	 * analogous feature in EJB.
	 * <p><b>NOTE:</b> Actual creation of a nested transaction will only work on
	 * specific transaction managers. Out of the box, this only applies to the JDBC
	 * {@link org.springframework.jdbc.datasource.DataSourceTransactionManager}
	 * when working on a JDBC 3.0 driver. Some JTA providers might support
	 * nested transactions as well.
	 * @see org.springframework.jdbc.datasource.DataSourceTransactionManager
	 */
	int PROPAGATION_NESTED = 6;


	/**
	 * Use the default isolation level of the underlying datastore.
	 * All other levels correspond to the JDBC isolation levels.
	 * @see java.sql.Connection
	 */
	int ISOLATION_DEFAULT = -1;

	/**
	 * Indicates that dirty reads, non-repeatable reads and phantom reads
	 * can occur.
	 * <p>This level allows a row changed by one transaction to be read by another
	 * transaction before any changes in that row have been committed (a "dirty read").
	 * If any of the changes are rolled back, the second transaction will have
	 * retrieved an invalid row.
	 * @see java.sql.Connection#TRANSACTION_READ_UNCOMMITTED
	 */
	int ISOLATION_READ_UNCOMMITTED = 1;  // same as java.sql.Connection.TRANSACTION_READ_UNCOMMITTED;

	/**
	 * Indicates that dirty reads are prevented; non-repeatable reads and
	 * phantom reads can occur.
	 * <p>This level only prohibits a transaction from reading a row
	 * with uncommitted changes in it.
	 * @see java.sql.Connection#TRANSACTION_READ_COMMITTED
	 */
	int ISOLATION_READ_COMMITTED = 2;  // same as java.sql.Connection.TRANSACTION_READ_COMMITTED;

	/**
	 * Indicates that dirty reads and non-repeatable reads are prevented;
	 * phantom reads can occur.
	 * <p>This level prohibits a transaction from reading a row with uncommitted changes
	 * in it, and it also prohibits the situation where one transaction reads a row,
	 * a second transaction alters the row, and the first transaction re-reads the row,
	 * getting different values the second time (a "non-repeatable read").
	 * @see java.sql.Connection#TRANSACTION_REPEATABLE_READ
	 */
	int ISOLATION_REPEATABLE_READ = 4;  // same as java.sql.Connection.TRANSACTION_REPEATABLE_READ;

	/**
	 * Indicates that dirty reads, non-repeatable reads and phantom reads
	 * are prevented.
	 * <p>This level includes the prohibitions in {@link #ISOLATION_REPEATABLE_READ}
	 * and further prohibits the situation where one transaction reads all rows that
	 * satisfy a {@code WHERE} condition, a second transaction inserts a row
	 * that satisfies that {@code WHERE} condition, and the first transaction
	 * re-reads for the same condition, retrieving the additional "phantom" row
	 * in the second read.
	 * @see java.sql.Connection#TRANSACTION_SERIALIZABLE
	 */
	int ISOLATION_SERIALIZABLE = 8;  // same as java.sql.Connection.TRANSACTION_SERIALIZABLE;


	/**
	 * Use the default timeout of the underlying transaction system,
	 * or none if timeouts are not supported.
	 */
	int TIMEOUT_DEFAULT = -1;
....
}
 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值