事务

欢迎光临我的博客[http://poetize.cn],前端使用Vue2,聊天室使用Vue3,后台使用Spring Boot

事务四个特性:ACID

  1. 原子性(Atomicity):事务的原子性确保动作要么全部完成,要么完全不起作用。
  2. 一致性(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。
  3. 隔离性(Isolation):可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
  4. 持久性(Durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久化存储器中。

JDBC事务

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>

Java持久化API事务(JPA)

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

传播行为

传播行为 含义
PROPAGATION_REQUIRED(常用)(默认) 表示当前方法必须运行在事务中。如果当前当前事务存在,方法将会在该事务中运行。否则,会启动一个新的事务
PROPAGATION_REQUIRED_NEW(常用) 表示当前方法必须运行在它自己的事务中。一个新的事务将被启动。如果存在当前事务,在该方法执行期间,当前事务会被挂起。(一旦内层事务进行了提交后,外层事务不能对其进行回滚)
PROPAGATION_SUPPORTS 支持事务但不必须,如果存在当前事务的话,那么该方法会在这个事务中运行
PROPAGATION_MANDATORY 表示该方法必须在事务中运行,如果当前事务不存在,则会抛出一个异常
PROPAGATION_NOT_SUPPORTED 表示该方法不应该运行在事务中。如果存在当前事务,在该方法运行期间,当前事务将被挂起。
PROPAGATION_NEVER 表示当前方法不应该运行在事务上下文中。如果当前正有一个事务在运行,则会抛出异常
PROPAGATION_NESTED 表示如果当前已经存在一个事务,那么该方法将会在嵌套事务中运行。嵌套的事务可以独立于当前事务进行单独地提交或回滚。如果当前事务不存在,那么其行为与PROPAGATION_REQUIRED一样。

脏读

事务1修改了某条记录
事务2读取了这条记录
事务1回滚了这条记录,因此事务2读取的是无效值

不可重复读

事务1读取了某条记录
事务2修改了这条记录(已提交)
事务1再次读取这条记录,和第一次读取的记录不一样

幻读

事务1读取了某表的部分行数据
事务2向此表插入了新的行(已提交)
事务1再次读取此表,多出了一些行

隔离级别(mysql都支持)

  1. 读未提交(ISOLATION_READ_UNCOMMITTED)(都不能避免)
  2. 读已提交(ISOLATION_READ_COMMITTED)(脏读可避免)(开发常用)
    • 事务1只能读取事务2已提交的数据
  3. 可重复读(ISOLATION_REPEATABLE_READ)(行上锁:脏读与不可重复读可避免)(mysql默认)
    • 执行事务期间禁止其他事务对此字段进行更新
  4. 串行化(ISOLATION_SERIALIZABLE)(表上锁:都可避免,性能最差)

编程式事务(允许用户在代码中精确定义事务的边界)

使用TransactionTemplate

    TransactionTemplate tt = new TransactionTemplate();    //新建一个TransactionTemplate
    Object result = tt.execute(
        new TransactionCallback(){
            public Object doTransaction(TransactionStatus status){
                updateOperation();
                //使用TransactionCallback()可以返回一个值。如果使用TransactionCallbackWithoutResult则没有返回值。
                return resultOfUpdateOperation();
            }
    });    // 执行execute方法进行事务管理


使用PlatformTransactionManager

    //定义一个某个框架平台的TransactionManager,如JDBC、Hibernate
    DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
    dataSourceTransactionManager.setDataSource(dataSource);    // 设置数据源
    DefaultTransactionDefinition transDef = new DefaultTransactionDefinition();    //定义事务属性
    transDef.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRED);    //设置传播行为属性
    TransactionStatus status = dataSourceTransactionManager.getTransaction(transDef);    //获得事务状态
    try {
        // 数据库操作
        dataSourceTransactionManager.commit(status);    //提交
    } catch (Exception e) {
        dataSourceTransactionManager.rollback(status);    //回滚
    }
posted @ 2019-09-06 09:24  LittleDonkey  阅读(156)  评论(0编辑  收藏  举报