Spring事务,详解编程式,声明式事务管理

it2026-02-05  0

Spring 事务

spring的事务就是对数据库事务的包装,数据库的事务说简单就只有开启, 回滚和关闭, 所以Spring事务的原理就是拿一个数据连接,根据spring的事务配置,操作这个数据连接,对数据库进行事务开启,回滚或关闭操作.但是spring除了实现这些,还配合spring的传播行为对事务进行了更广泛的管理。

原生的JDBC事务操作:

connect.setAutoCommit (false) // 默认自动提交, 关闭自动提交 connect.commit(); //提交 connect.rollback(); //回滚

框架中对事务处理 : 封装这种复杂、复用性比较低的代码

七大传播行为,五大隔离级别: Spring在 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 = 1; int ISOLATION_READ_COMMITTED = 2; int ISOLATION_REPEATABLE_READ = 4; int ISOLATION_SERIALIZABLE = 8; //默认事务的最大执行时间 int TIMEOUT_DEFAULT = -1; //是否只读 default boolean isReadOnly() { return false; }

Spring两种事务管理方式:

编程式事务管理方式声明式事务管理方式

编程式事务管理方式: 使用java代码来管理事务,主要参与类:

PlatformTransactionManager,TransactionDefinition,TransactionStatus

代码实现:

<!--配置数据源--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/TEST"/> <property name="username" value="root"/> <property name="password" value="password"/> </bean> @Autowired private DataSource dataSource; private DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource); public void transactionTest(){ DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition(); //开启一个事务 TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition); try{ // A 账户余额 - 100 // B 余额余额 + 100 //提交 transactionManager.commit(transactionStatus); }catch (Exception e){ //回滚 transactionManager.rollback(transactionStatus); System.out.println(e.toString()); } }

可以发现编程式事务管理方式,事务操作内嵌到了业务代码中, 不利于程序解耦。现在 我们一般程序开发都使用的是声明式的事务管理方式

声明式事务管理方式: Spring 的声明式事务管理在底层是建立在 AOP 的基础之上的。 其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。

优点: 不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过等价的基于注解的方式), 便可以将事务规则应用到业务逻辑中。

缺点: 声明式事务唯一不足地方是,后者的最细粒度只能作用到方法级别, 无法做到像编程式事务那样可以作用到代码块级别。

基于注解实现声明式事务管理: 首先在配置文件中配置: 数据源,事务管理器, 开启事务注解 :

<!--配置数据源--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/TEST"/> <property name="username" value="root"/> <property name="password" value="password"/> </bean> <!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 开启注解事务 --> <tx:annotation-driven transaction-manager="transactionManager"/>

那么在程序方法上就可以使用注解: @Transactional, 实现声明式事务管理。

@Transactional中的属性

@AliasFor("transactionManager") String value() default ""; Propagation propagation() default Propagation.REQUIRED; //传播方式 Isolation isolation() default Isolation.DEFAULT; //隔离级别 int timeout() default TransactionDefinition.TIMEOUT_DEFAULT; //事务最大运行时间 boolean readOnly() default false; //是否只读

属性中的值,Propagation , Isolation 都是枚举类型, 实际上就是对TransactionDefinition类中属性进行了一次封装 如Propagetion中: `

REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED), SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),

Isolation中:

DEFAULT(TransactionDefinition.ISOLATION_DEFAULT), READ_UNCOMMITTED(TransactionDefinition.ISOLATION_READ_UNCOMMITTED),
最新回复(0)