博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring 事务管理
阅读量:4223 次
发布时间:2019-05-26

本文共 5821 字,大约阅读时间需要 19 分钟。

事务的定义

事务是一个操作集合,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。

事务的特性

在一个事务性操作的环境下,操作有着以下的4种特性,被称为ACID特性:

  • 原子性(Atomicity):当事务结束,它对所有资源状态的改变都被视为一个操作,这些操作要不同时成功,要不同时失败;
  • 一致性(Consistency):操作完成后,所有数据必须符合业务规则,否则事务必须中止;
  • 隔离性(Isolation):事务以相互隔离的方式执行,事务以外的实体无法知道事务过程中的中间状态;
  • 持久性(Durable):事务提交后,数据必须以一种持久性方式存储起来。

Spring事务接口

Spring事务管理高层抽象主要包括3个接口

这里写图片描述

PlatformTransactionManager 事务管理器(提交、回滚事务)

public interface PlatformTransactionManager {
TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException; void commit(TransactionStatus status) throws TransactionException; void rollback(TransactionStatus status) throws TransactionException;}

Spring为不同的持久化框架提供了不同的PlatformTransactionManager接口实现。如:

  • 使用Spring JDBC或iBatis进行持久化数据时使用DataSourceTransactionManager
  • 使用Hibernate3.0版本进行持久化数据时使用HibernateTransactionManager

TransactionDefinition 事务定义信息(隔离、传播、超时、只读)

public interface TransactionDefinition {    int PROPAGATION_REQUIRED = 0;    int PROPAGATION_SUPPORTS = 1;    int PROPAGATION_MANDATORY = 2;    int PROPAGATION_REQUIRES_NEW = 3;    int PROPAGATION_NOT_SUPPORTED = 4;    int PROPAGATION_NEVER = 5;    int PROPAGATION_NESTED = 6;    int ISOLATION_DEFAULT = -1;    int ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED;    int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;    int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;    int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;    int TIMEOUT_DEFAULT = -1;    int getPropagationBehavior();    int getIsolationLevel();    int getTimeout();    boolean isReadOnly();    String getName();}

事务隔离级别:(五种)

  • DEFAULT–使用后端数据库默认的隔离级别(Spring中的选择项);
  • READ_UNCOMMITED–允许你读取还未提交的改变了的数据。可能导致脏、幻、不可重复读;
  • READ_COMMITTED–允许在并发事务已经提交后读取。可防止脏读,但幻读和不可重复读仍可发生;
  • REPEATABLE_READ–对相同字段的多次读取是一致的,除非数据被事务本身改变。可防止脏、不可重复读,但幻读仍可能发生;
  • SERIALIZABLE–完全服从ACID的隔离级别,确保不发生脏、幻、不可重复读。这在所有的隔离级别中是最慢的,它是典型的通过完全锁定在事务中涉及的数据表来完成的;
  • 其中,MySQL默认采用REPEATABLE_READ隔离级别;Oracle默认采用READ_COMMITTED隔离级别

事务传播行为:(七种)

  • REQUIRED–支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择;
  • SUPPORTS–支持当前事务,如果当前没有事务,就以非事务方式执行;
  • MANDATORY–支持当前事务,如果当前没有事务,就抛出异常;
  • REQUIRES_NEW–新建事务,如果当前存在事务,把当前事务挂起;
  • NOT_SUPPORTED–以非事务方式执行操作,如果当前存在事务,就把当前事务挂起;
  • NEVER–以非事务方式执行,如果当前存在事务,则抛出异常;
  • NESTED–如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与REQUIRED类似的操作。拥有多个可以回滚的保存点,内部回滚不会对外部事务产生影响。只对DataSourceTransactionManager有效。

事务超时

为了使应用程序很好地运行,事务不能运行太长的时间。因为事务可能涉及对后端数据库的锁定,所以长时间的事务会不必要的占用数据库资源。事务超时就是事务的一个定时器,在特定时间内事务如果没有执行完毕,那么就会自动回滚,而不是一直等待其结束。

回滚规则

事务五边形的最后一个方面是一组规则,这些规则定义了哪些异常会导致事务回滚而哪些不会。默认情况下,事务只有遇到运行期异常时才会回滚,而在遇到检查型异常时不会回滚(这一行为与EJB的回滚行为是一致的)。但是你可以声明事务在遇到特定的检查型异常时像遇到运行期异常那样回滚。同样,你还可以声明事务遇到特定的异常不回滚,即使这些异常是运行期异常。

TransactionStatus 事务具体运行状态

public interface TransactionStatus{
boolean isNewTransaction(); // 是否是新的事物 boolean hasSavepoint(); // 是否有恢复点 void setRollbackOnly(); // 设置为只回滚 boolean isRollbackOnly(); // 是否为只回滚 boolean isCompleted; // 是否已完成}

Spring事务的使用

Spring提供了对编程式事务和声明式事务的支持,编程式事务允许用户在代码中精确定义事务的边界,而声明式事务(基于AOP)有助于用户将操作与事务规则进行解耦。

简单地说,编程式事务侵入到了业务代码里面,但是提供了更加详细的事务管理;而声明式事务由于基于AOP,所以既能起到事务管理的作用,又可以不影响业务代码的具体实现。

编程式事务

Spring提供两种方式的编程式事务管理,分别是:使用TransactionTemplate和直接使用PlatformTransactionManager。

使用TransactionTemplate

// 新建一个TransactionTemplateTransactionTemplate tt = new TransactionTemplate();     Object result = tt.execute(        new TransactionCallback(){              public Object doTransaction(TransactionStatus status){                  updateOperation();                  return resultOfUpdateOperation();              }      });

使用PlatformTransactionManager

//定义一个某个框架平台的TransactionManager,如JDBC、Hibernate// 设置数据源dataSourceTransactionManager.setDataSource(this.getJdbcTemplate().getDataSource()); // 定义事务属性DefaultTransactionDefinition transDef = new DefaultTransactionDefinition(); // 设置传播行为属性transDef.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRED); // 获得事务状态TransactionStatus status = dataSourceTransactionManager.getTransaction(transDef); try {        // 数据库操作        // 提交        dataSourceTransactionManager.commit(status);    } catch (Exception e) {        // 回滚        dataSourceTransactionManager.rollback(status);    }

声明式事务

根据代理机制的不同,总结了五种Spring事务的配置方式,配置文件如下:

每个Bean都有一个代理

PROPAGATION_REQUIRED

所有Bean共享一个代理基类

PROPAGATION_REQUIRED

使用拦截器

PROPAGATION_REQUIRED
*Dao
transactionInterceptor

使用tx标签配置的拦截器

全注解

@Transactional@Component("userDao")public class UserDaoImpl extends HibernateDaoSupport implements UserDao {
public List
listUsers() { return this.getSession().createQuery("from User").list(); } }
你可能感兴趣的文章
UVM:7.7.4 扩展位宽
查看>>
UVM:7.8.1 get_root_blocks
查看>>
UVM:7.8.2 get_reg_by_offset 函数
查看>>
UVM:8.2.2 重载的方式及种类
查看>>
UVM:8.2.3 复杂的重载
查看>>
UVM:8.2.4 factory 机制的调试
查看>>
UVM:8.3.1 重载transaction
查看>>
UVM:8.3.2 重载sequence
查看>>
leetcode171.[math] Excel Sheet Column Number
查看>>
Log4j配置
查看>>
java发送https请求
查看>>
java发送https请求证书问题
查看>>
js新消息提醒
查看>>
js窗体消息提醒
查看>>
深入Hibernate映射文件(二)——<hibernate-mapping>的属性
查看>>
详解在Spring中进行集成测试
查看>>
Struts2中过滤器和拦截器的区别
查看>>
51单片机:led灯闪烁10次后熄灭
查看>>
安卓:okhttp请求,获取返回数据
查看>>
安卓:股票筛选及分析系统
查看>>