【Spring Cloud Alibaba】分布式事务 Seata
Seata的分布式事务解决方案是业务层面的解决方案,只依赖于单台数据库的事务能力。 Seata框架中一个分布式事务包含3中角色: Transaction Coordinator (TC): 事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚。 Transaction Manager ™: 控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议。
1 @Transactional注解
@Transactional是Spring 事务管理提供的注解,在一个方法中加上了这个注解,那么这个方法就将是有事务的,方法内的操作要么一起提交、要么一起回滚
@Target({
ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
/**
* 当在配置文件中有多个 TransactionManager , 可以用该属性指定选择哪个事务管理器。
*/
@AliasFor("transactionManager")
String value() default "";
/**
* 同上。
*/
@AliasFor("value")
String transactionManager() default "";
/**
* 事务的传播行为,默认值为 REQUIRED。
*/
Propagation propagation() default Propagation.REQUIRED;
/**
* 事务的隔离规则,默认值采用 DEFAULT。
*/
Isolation isolation() default Isolation.DEFAULT;
/**
* 事务超时时间。
*/
int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
/**
* 是否只读事务
*/
boolean readOnly() default false;
/**
* 用于指定能够触发事务回滚的异常类型。
*/
Class<? extends Throwable>[] rollbackFor() default {
};
/**
* 同上,指定类名。
*/
String[] rollbackForClassName() default {
};
/**
* 用于指定不会触发事务回滚的异常类型
*/
Class<? extends Throwable>[] noRollbackFor() default {
};
/**
* 同上,指定类名
*/
String[] noRollbackForClassName() default {
};
}
@Transactional注解最常见的应用
- 可以标注在类、方法和接口(不要这样用)上;且方法上的注解会覆盖类上的注解
- 标注在方法上,标识开启事务功能,正常则提交、异常则回滚
- 自行指定rollbackFor属性,让Checked Exception 也能够实现回滚
- 让TestCase 也能够实现回滚
测试用例@Transactional的使用
/**
* <h2> testTransactional01 - 测试事务时会回滚事务 - 执行后会回滚<h2>
* @Transactional 如果为提交则不会回滚
* version: 1.0 - 2022/3/8
*/
@Transactional
@Test
public void testTransactional01(){
//数据库存储操作
}
/**
* <h2> testTransactional02 - 测试事务时会回滚事务 - 指定不回滚 - 即使发生异常也不会回滚<h2>
* version: 1.0 - 2022/3/8
*/
@Rollback(value = false)
@Transactional
@Test
public void testTransactional02(){
//数据库存储操作
throw new RuntimeException("error");
}
@Transactional注解失效的场景
- 把注解标注在非public修饰的方法上
- propagation(传播行为)属性配置错误(不合理)rollbackFor属性设置错误
- 在同一个类中方法调用,导致事务失效
- 自己主动去catch,代表『没有出现』异常,导致事务失效
- 数据库引擎本身就不支持事务(例如MyISAM ),当然也不会生效
在同一个类中方法调用,如下列代码调用wrongRollbackFor会导致事务失效
@Transactional
@Override
public void wrongRollbackFor() throws Exception {
//数据上的操作
throw new RuntimeException("发生异常,测试@Transactional");
}
@Override
public void wrongInnweCall() throws Exception {
wrongRollbackFor();
}
2 分布式事务解决方案
分布式事务是来源于微服务的(或类似的场景),服务之间存在着调用,且整个调用链路上存在着多处(分布在不同的微服务上)写数据表的行为,那么,分布式事务就要保证这些操作要么全部成功,要么全部失败