Spring——编程式事务
目录
platformtransactionManager
TransactionDefinition
TransactionStatus
编程式事务
PlatformTransactionManager手动管理事务
TransactionTemplate管理事务
platformtransactionManager
platformtransactionManager是spring处理事务的核心接口,为不同的事务管理实现提供了一个统一的编程模型。Spring本身不管理事务,而是通过这个接口适配各种底层的事务机制。该接口有3个方法。
public interface PlatformTransactionManager {// 获取一个事务(根据定义创建或加入已有事务)TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;// 提交事务void commit(TransactionStatus status) throws TransactionException;// 回滚事务void rollback(TransactionStatus status) throws TransactionException; }
核心方法说明:
getTransaction(TransactionDefinition definition)
- 根据事务定义(传播行为、隔离级别、超时等)获取一个事务。
- 如果当前线程已有事务,根据传播行为决定是加入还是新建。
- 返回
TransactionStatus
对象,表示当前事务状态。
commit(TransactionStatus status)
- 提交事务。
- 如果事务已标记为
rollback-only
,则执行回滚。
rollback(TransactionStatus status)
- 回滚事务。
TransactionDefinition
TransactionDefinition用于定义事务的属性,描述事务的边界和行为规则。
主要内容:
- 传播行为(Propagation)
REQUIRED
(默认):如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务
REQUIRES_NEW
:创建一个新的事务,如果当前存在事务,则把当前事务挂起
NESTED
:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务;如果当前没有事务,则等价于REQUIRED
SUPPORTS
:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行
NOT_SUPPORTED
:以非事务方式运行,如果当前存在事务,则把当前事务挂起
NEVER
:以非事务方式运行,如果当前存在事务,则抛出异常
MANDATORY
:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常- 隔离级别(Isolation)
DEFAULT
:使用底层数据库的默认隔离级别
READ_UNCOMMITTED
:读未提交
READ_COMMITTED
:读已提交
REPEATABLE_READ
:可重复读
SERIALIZABLE
:串行化- 超时时间(Timeout)
- 是否只读(Read-only)
TransactionStatus
TransactionStatus接口表示事务的状态,用于在事务的执行过程中查询状态和控制事务。
public interface TransactionStatus extends SavepointManager {// 判断是否是新的事务boolean isNewTransaction();// 判断是否有保存点boolean hasSavepoint();// 设置事务为只回滚void setRollbackOnly();// 判断事务是否已被标记为只回滚boolean isRollbackOnly();// 判断事务是否已完成boolean isCompleted();
}
编程式事务
编程式事务可以在代码中显示的调用事务管理API来控制事务边界。
PlatformTransactionManager手动管理事务
首先在spring的配置文件中提供一个事务管理器:
<bean class="org.springframework.transaction.support.TransactionTemplate" id="transactionTemplate"><property name="transactionManager" ref="transactionManager"/> </bean>
然后注入到service层,并且编写对应的方法,这里使用ORM的是mybatis:
public class UserService {@AutowiredPlatformTransactionManager platformTransactionManager;@AutowiredUserDao userDao;public void trans(){//1.定义默认的事务属性DefaultTransactionDefinition definition = new DefaultTransactionDefinition();//2.获取TransactionStatusTransactionStatus transaction = platformTransactionManager.getTransaction(definition);try{userDao.updateUsernameById(1,"6k");platformTransactionManager.commit(transaction);}catch (Exception e){platformTransactionManager.rollback(transaction);}} }
运行启动调用这个方法之后发现确实修改成功了,看起来加没加事务没有什么区别。接下来在后面抛个异常:
发现即使已经调用了接口中的方法,数据依旧没有修改,说明这个事务被回滚了!
TransactionTemplate管理事务
依旧在spring配置文件中提供事务管理器./
<bean class="org.springframework.transaction.support.TransactionTemplate" id="transactionTemplate"><property name="transactionManager" ref="transactionManager"/>
</bean>
注入TransactionTemplate
@Autowired
TransactionTemplate transactionTemplate;
/*** 基于TransactionTemplate的编程式事务方法(trans2)* 说明:TransactionTemplate是Spring提供的事务模板类,简化了编程式事务的代码(无需手动commit/rollback)*/
public void trans2(){// 调用TransactionTemplate的execute方法,传入事务回调接口(TransactionCallbackWithoutResult)transactionTemplate.execute(new TransactionCallbackWithoutResult() {// 重写回调接口的doInTransactionWithoutResult方法// 作用:该方法内的代码会运行在事务环境中,TransactionStatus参数用于控制事务状态(如标记回滚)@Overrideprotected void doInTransactionWithoutResult(TransactionStatus status) {try{// 说明:此操作会被Spring事务管理,若后续出现异常,该更新会被回滚userDao.updateUsernameById(1,"ojbk");int i = 1/0;}catch (Exception e){// 异常处理:当业务逻辑抛出异常时,手动标记事务为“需要回滚”status.setRollbackOnly();}}} );
}