docs/Spring全家桶/Spring源码分析/Spring事务/Spring事务(三):事务的隔离级别与传播方式的处理01.md
һƪµᵽִ TransactionAspectSupport#invokeWithinTransaction УĽ̽ spring ơ
עֵ̽ݿ mysqlݿܻ졣
ʽԴǰһЩǰ֪ʶҪ˽һµģҪ spring ص
Ĵ ACIDо£
AtomicityConsistencyIsolationDurabilityĸ뼶ǶԸԣIsolationĽһ֣Щ뼶£
δύύظлЩIJص㻹ǹע spring صݣspring 뼶Ķ org.springframework.transaction.annotation.Isolation У£
public enum Isolation {
/**
* Ĭֵø뼶ʹõݿõĸ뼶
*/
DEFAULT(TransactionDefinition.ISOLATION_DEFAULT),
/**
* δύ
*/
READ_UNCOMMITTED(TransactionDefinition.ISOLATION_READ_UNCOMMITTED),
/**
* ύ
*/
READ_COMMITTED(TransactionDefinition.ISOLATION_READ_COMMITTED),
/**
* ظ
*/
REPEATABLE_READ(TransactionDefinition.ISOLATION_REPEATABLE_READ),
/**
* л
*/
SERIALIZABLE(TransactionDefinition.ISOLATION_SERIALIZABLE);
...
}
ǿʹ @Transactional ע isolation ø뼶
@Transactional ע timeout óʱʱֻģʽƽʱûûõ鵽һЩ˵Ϊֻģʽеĸֻֻвдʵд֤@Transactional ע readOnly ֻģʽһA ʽB B еA``A ִɺB ˣʾ£
class A {
//
@Transactional
public void methdA() {
// һЩ
...
}
}
class B {
//
@Transactional
public void methodB() {
// 1. һЩ
...
// 2. methodA()
a.methodA();
// 3. ﱨ
throw new RuntimeException();
}
}
ڿB һعģôA ҪҪعأ
A B ͬһA ӦҲҪعA B ִУA ִB ıأA ͲӦûعΪ˴־ףspring Ĵĸǿʹ @Transactional ע propagation ֻģʽ
public @interface Transactional {
...
// ĬϵļΪ Propagation.REQUIRED
Propagation propagation() default Propagation.REQUIRED;
}
spring һ 7 Ĵͣо£
| Ϊ | |
|---|---|
PROPAGATION_REQUIRED | Ĭֵ衿ǰУǰ߳ûһµǰ߳ѾڸС |
PROPAGATION_MANDATORY | ǿơǰУǰ߳в**׳쳣** |
PROPAGATION_SUPPORTS | ֧֡ǰʱҪǰ߳дʱ |
PROPAGATION_REQUIRES_NEW | ǰڶУǰ߳Ѿ¿һֱнٻָ֮ǰ |
PROPAGATION_NESTED | ǶסǰУǰ߳дע****γǶǶе쳣Ӱ쵽֮ǰIJ |
PROPAGATION_NOT_SUPPORTED | ֧֡ǰУǰ߳дֱн |
PROPAGATION_NEVER | ǰУǰ߳д**׳쳣** |
ע͵
PROPAGATION_REQUIRED PROPAGATION_MANDATORY
PROPAGATION_REQUIREDҪУû****PROPAGATION_MANDATORYҪУû쳣PROPAGATION_NOT_SUPPORTED PROPAGATION_NEVER
PROPAGATION_NOT_SUPPORTEDУ****PROPAGATION_NEVERУ쳣PROPAGATION_REQUIRES_NEW PROPAGATION_NESTED
PROPAGATION_REQUIRES_NEWִɺֻععִб¾һعPROPAGATION_NESTEDִɺع㣻ִбҲǻعȷϸͿʼˣ demo
һЩã
@Configuration
@ComponentScan("org.springframework.learn.tx.demo03")
@EnableTransactionManagement(proxyTargetClass = true)
public class TxDemo03Config {
/**
* Դ
*/
@Bean
public DataSource dataSource() throws Exception {
Driver driver = new com.mysql.jdbc.Driver();
String url = "jdbc:mysql://localhost:3306/test";
String username = "root";
String password = "123";
return new SimpleDriverDataSource(driver, url, username, password);
}
/**
* jdbcTemplateݿIJ
*/
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
/**
*
*/
@Bean
public DataSourceTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
ϴ˵£
SimpleDriverDataSourceԴܲ࣬ʺ demojdbcTemplateΪһ demo mybatis``jpaDataSourceTransactionManager ԵԴ˵ȫһ mysql IJҪ
@Service
public class UserService {
@Autowired
private JdbcTemplate jdbcTemplate;
/**
* ݿʹ @Transactional
*/
@Transactional(rollbackFor = Exception.class)
public int insert() {
String sql = "insert into `user`(`login_name`, `nick`, `create_time`, `update_time`)"
+ "values (?, ?, ?, ?)";
int result = jdbcTemplate.update(sql, "test", "test", new Date(), new Date());
if(true) {
//throw new RuntimeException("׳쳣");
}
System.out.println(result);
return result;
}
}
ࣺ
public class TxDemo03Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext
= new AnnotationConfigApplicationContext(TxDemo03Config.class);
UserService userService = applicationContext.getBean(UserService.class);
userService.insert();
}
}
demo ʮּͲˣǽͨ demo һЩȲ̽ spring ĸ뼶𡢴ʽĴ
TransactionAspectSupport#invokeWithinTransactionһƪǾ˵Ĵ TransactionAspectSupport#invokeWithinTransaction ǽص
ϴ룺
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
TransactionAttributeSource tas = getTransactionAttributeSource();
// 1. ȡ @Transactional
final TransactionAttribute txAttr = (tas != null
? tas.getTransactionAttribute(method, targetClass) : null);
// 2. ȡIOCлȡ
final TransactionManager tm = determineTransactionManager(txAttr);
// ⲿֵĴ TransactionManager ReactiveTransactionManager
...
// 3. TransactionManager תΪ PlatformTransactionManager
PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
// 4. ȡȫʽΪ".."
final String joinpointIdentification
= methodIdentification(method, targetClass, txAttr);
if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
// 5. ȡϢ↑
TransactionInfo txInfo = createTransactionIfNecessary(
ptm, txAttr, joinpointIdentification);
Object retVal;
try {
// 6. ִоҵ
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// 7. 쳣ع
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
// 8. ϢǽϢΪɵ
cleanupTransactionInfo(txInfo);
}
if (vavrPresent && VavrDelegate.isVavrTry(retVal)) {
TransactionStatus status = txInfo.getTransactionStatus();
if (status != null && txAttr != null) {
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
}
// 9. ύ
commitTransactionAfterReturning(txInfo);
return retVal;
}
else {
// CallbackPreferringPlatformTransactionManager ͵ TransactionManager
...
}
}
TransactionAspectSupport#invokeWithinTransaction ݣעϸ˵ΪЩִй̡
@Transactionalǻȡ UserService#insert ϱǵ @Transactional ãõĽ£
ȡķΪ TransactionAspectSupport#determineTransactionManagerֱӿ룺
protected TransactionManager determineTransactionManager(@Nullable TransactionAttribute txAttr) {
if (txAttr == null || this.beanFactory == null) {
return getTransactionManager();
}
// @Transaction עָʹspringлȡ
String qualifier = txAttr.getQualifier();
if (StringUtils.hasText(qualifier)) {
return determineQualifiedTransactionManager(this.beanFactory, qualifier);
}
// ָƣҲǴspringлȡ
else if (StringUtils.hasText(this.transactionManagerBeanName)) {
return determineQualifiedTransactionManager(
this.beanFactory, this.transactionManagerBeanName);
}
else {
// ֱָӷ
TransactionManager defaultTransactionManager = getTransactionManager();
if (defaultTransactionManager == null) {
// ӻлȡĬϵ
defaultTransactionManager = this.transactionManagerCache
.get(DEFAULT_TRANSACTION_MANAGER_KEY);
if (defaultTransactionManager == null) {
// ʹ spring лȡһ
defaultTransactionManager = this.beanFactory.getBean(TransactionManager.class);
this.transactionManagerCache.putIfAbsent(
DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);
}
}
return defaultTransactionManager;
}
}
Ȼе㳤dzԸ÷ܽ£
@Transaction עָʹ spring лȡTransactionManager beanTxDemo03Config УΪ DataSourceTransactionManager
public DataSourceTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
õҲ DataSourceTransactionManager
TransactionManager תΪ PlatformTransactionManagerûɶ˵ģDataSourceTransactionManager PlatformTransactionManager ࣬һת
private PlatformTransactionManager asPlatformTransactionManager(
@Nullable Object transactionManager) {
if (transactionManager == null || transactionManager instanceof PlatformTransactionManager) {
return (PlatformTransactionManager) transactionManager;
} else {
// 쳣
...
}
}
һõȫʽΪ"͡"Ҳûɶ˵ģһõĽ£
ƪľȷˣƪǼ
ԭӣhttps://my.oschina.net/funcy/blog/4773459 ߸ˮƽд֮ӭָԭףҵתϵȨҵתע