springboot 事务使用说明
自动配置类
TransactionAutoConfiguration
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnClass({PlatformTransactionManager.class}) //在PlatformTransactionManager存在时创建自动配置类
@AutoConfigureAfter({JtaAutoConfiguration.class, HibernateJpaAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, Neo4jDataAutoConfiguration.class})
//在这些配置类后创建
@EnableConfigurationProperties({TransactionProperties.class}) //自动配置属性类
public class TransactionAutoConfiguration {
public TransactionAutoConfiguration() {
}
@Bean
@ConditionalOnMissingBean
public TransactionManagerCustomizers platformTransactionManagerCustomizers(ObjectProvider<PlatformTransactionManagerCustomizer<?>> customizers) {
return new TransactionManagerCustomizers((Collection)customizers.orderedStream().collect(Collectors.toList()));
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnSingleCandidate(ReactiveTransactionManager.class)
public TransactionalOperator transactionalOperator(ReactiveTransactionManager transactionManager) {
return TransactionalOperator.create(transactionManager);
}
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnBean({TransactionManager.class})
@ConditionalOnMissingBean({AbstractTransactionManagementConfiguration.class})
public static class EnableTransactionManagementConfiguration {
public EnableTransactionManagementConfiguration() {
}
@Configuration(
proxyBeanMethods = false
)
@EnableTransactionManagement(
proxyTargetClass = true
)
@ConditionalOnProperty(
prefix = "spring.aop",
name = {"proxy-target-class"},
havingValue = "true",
matchIfMissing = true
) //cglib动态代理,默认使用cglib创建代理对象
public static class CglibAutoProxyConfiguration {
public CglibAutoProxyConfiguration() {
}
}
@Configuration(
proxyBeanMethods = false
)
@EnableTransactionManagement(
proxyTargetClass = false
)
@ConditionalOnProperty(
prefix = "spring.aop",
name = {"proxy-target-class"},
havingValue = "false"
) //jdk动态代理,当spring.aop.proxy-target-class=false,且当前类有接口时,使用jdk创建代理对象
public static class JdkDynamicAutoProxyConfiguration {
public JdkDynamicAutoProxyConfiguration() {
}
}
}
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnSingleCandidate(PlatformTransactionManager.class)
public static class TransactionTemplateConfiguration {
public TransactionTemplateConfiguration() {
}
@Bean
@ConditionalOnMissingBean({TransactionOperations.class})
public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager) {
return new TransactionTemplate(transactionManager);
}
}
}
TransactionProperties
@ConfigurationProperties(
prefix = "spring.transaction"
)
public class TransactionProperties implements PlatformTransactionManagerCustomizer<AbstractPlatformTransactionManager> {
@DurationUnit(ChronoUnit.SECONDS)
private Duration defaultTimeout; //事务默认超时时间
private Boolean rollbackOnCommitFailure; //事务提交失败是否回滚
public TransactionProperties() {
}
public Duration getDefaultTimeout() {
return this.defaultTimeout;
}
public void setDefaultTimeout(Duration defaultTimeout) {
this.defaultTimeout = defaultTimeout;
}
public Boolean getRollbackOnCommitFailure() {
return this.rollbackOnCommitFailure;
}
public void setRollbackOnCommitFailure(Boolean rollbackOnCommitFailure) {
this.rollbackOnCommitFailure = rollbackOnCommitFailure;
}
public void customize(AbstractPlatformTransactionManager transactionManager) {
if (this.defaultTimeout != null) {
transactionManager.setDefaultTimeout((int)this.defaultTimeout.getSeconds());
}
if (this.rollbackOnCommitFailure != null) {
transactionManager.setRollbackOnCommitFailure(this.rollbackOnCommitFailure);
}
}
}
PlatformTransactionManagerCustomizer
@FunctionalInterface
public interface PlatformTransactionManagerCustomizer<T extends PlatformTransactionManager> {
void customize(T transactionManager);
}
DataSourceTransactionManager:数据源事务管理器
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnClass({JdbcTemplate.class, TransactionManager.class})
//需存在dbcTemplate、TransactionManager类
@AutoConfigureOrder(2147483647)
@EnableConfigurationProperties({DataSourceProperties.class}) //自动配置属性类DataSourceProperties
public class DataSourceTransactionManagerAutoConfiguration {
public DataSourceTransactionManagerAutoConfiguration() {
}
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnSingleCandidate(DataSource.class)
static class JdbcTransactionManagerConfiguration {
JdbcTransactionManagerConfiguration() {
}
@Bean
@ConditionalOnMissingBean({TransactionManager.class}) //不存在TransactionManager实例对象时,创建DataSourceTransactionManager对象
DataSourceTransactionManager transactionManager(Environment environment, DataSource dataSource, ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
DataSourceTransactionManager transactionManager = this.createTransactionManager(environment, dataSource);
transactionManagerCustomizers.ifAvailable((customizers) -> {
customizers.customize(transactionManager);
});
return transactionManager;
} //配置数据源事务管理器
private DataSourceTransactionManager createTransactionManager(Environment environment, DataSource dataSource) {
return (DataSourceTransactionManager)((Boolean)environment.getProperty("spring.dao.exceptiontranslation.enabled", Boolean.class, Boolean.TRUE) ? new JdbcTransactionManager(dataSource) : new DataSourceTransactionManager(dataSource));
}
}
}
DataSourceProperrties
@ConfigurationProperties(
prefix = "spring.datasource"
)
public class DataSourceProperties implements BeanClassLoaderAware, InitializingBean {
private ClassLoader classLoader;
private boolean generateUniqueName = true;
private String name;
private Class<? extends DataSource> type;
private String driverClassName;
private String url;
private String username;
private String password;
private String jndiName;
/** @deprecated */
@Deprecated
private DataSourceInitializationMode initializationMode;
/** @deprecated */
@Deprecated
private String platform;
private List<String> schema;
/** @deprecated */
@Deprecated
private String schemaUsername;
/** @deprecated */
@Deprecated
private String schemaPassword;
/** @deprecated */
@Deprecated
private List<String> data;
/** @deprecated */
@Deprecated
private String dataUsername;
/** @deprecated */
@Deprecated
private String dataPassword;
/** @deprecated */
@Deprecated
private boolean continueOnError;
/** @deprecated */
@Deprecated
private String separator;
/** @deprecated */
@Deprecated
private Charset sqlScriptEncoding;
private EmbeddedDatabaseConnection embeddedDatabaseConnection;
private DataSourceProperties.Xa xa;
private String uniqueName;
public DataSourceProperties() {
this.initializationMode = DataSourceInitializationMode.EMBEDDED;
this.platform = "all";
this.continueOnError = false;
this.separator = ";";
this.xa = new DataSourceProperties.Xa();
}
相关注解
@Transactional
@Target({ElementType.TYPE, ElementType.METHOD}) //标注在类、方法上
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
@AliasFor("transactionManager")
String value() default ""; //事务管理器
@AliasFor("value")
String transactionManager() default ""; //事务管理器
Propagation propagation() default Propagation.REQUIRED; //传播行为
Isolation isolation() default Isolation.DEFAULT; //隔离级别
int timeout() default -1; //超时时间,默认不限制
boolean readOnly() default false; //是否只读,默认false
Class<? extends Throwable>[] rollbackFor() default {}; //发生异常回滚
String[] rollbackForClassName() default {};
Class<? extends Throwable>[] noRollbackFor() default {}; //发生异常不回滚
String[] noRollbackForClassName() default {};
}
Propagation:传播行为,调用事务方法执行不同的事务操作
public enum Propagation {
REQUIRED(0), //默认,事务不存在新建事务,
//标注在被调用方法上时,如果调用方法的事务存在,使用调用方法的事务
//如果调用方法不存在事务,则新建事务
REQUIRES_NEW(3), //创建新的事务
NESTED(6); //如果数据库支持保存点(savepoint)则使用保存点,
//否则等同于requires_new,新建一个事务
SUPPORTS(1), //调用方法时,如果没有事务则不使用事务;如果有事务则使用当前事务
NOT_SUPPORTED(4), //不支持事务,事务不存在不会创建,
//存在则挂起事务,直到方法运行结束后继续事务
MANDATORY(2), //方法不存在事务,抛出异常
NEVER(5), //方法存在事务,抛出异常
private final int value;
private Propagation(int value) {
this.value = value;
}
public int value() {
return this.value;
}
}
Isolation:隔离级别,事务与事务之间的隔离方式
public enum Isolation {
DEFAULT(-1), //默认隔离级别
READ_UNCOMMITTED(1), //读未提交,一个事务可以读取另一个事务未提交的数据
READ_COMMITTED(2), //读提交,一个事务可以读取另一个事务提交的数据
REPEATABLE_READ(4), //可重复读,同一个事务中相同的sql读取的数据一样
SERIALIZABLE(8); //可序列化,事务串行执行(并发度低,高并发场景不能使用)
private final int value;
private Isolation(int value) {
this.value = value;
}
public int value() {
return this.value;
}
}
事务管理器
TransactionManager
public interface TransactionManager {
}
PlatformTransactionManager
public interface PlatformTransactionManager extends TransactionManager {
TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;
void commit(TransactionStatus status) throws TransactionException;
void rollback(TransactionStatus status) throws TransactionException;
}
TransactionStatus
public interface TransactionStatus extends TransactionExecution, SavepointManager, Flushable {
boolean hasSavepoint();
void flush();
}
TransactionExecution
public interface TransactionExecution {
boolean isNewTransaction();
void setRollbackOnly();
boolean isRollbackOnly();
boolean isCompleted();
}
SavepointManager
public interface SavepointManager {
Object createSavepoint() throws TransactionException;
void rollbackToSavepoint(Object savepoint) throws TransactionException;
void releaseSavepoint(Object savepoint) throws TransactionException;
}
Flushable
public interface Flushable {
/**
* Flushes this stream by writing any buffered output to the underlying
* stream.
*
* @throws IOException If an I/O error occurs
*/
void flush() throws IOException;
}
DataSourceTransactionManager
public class DataSourceTransactionManager extends AbstractPlatformTransactionManager implements ResourceTransactionManager, InitializingBean {
@Nullable
private DataSource dataSource;
private boolean enforceReadOnly;
public DataSourceTransactionManager() {
this.enforceReadOnly = false;
this.setNestedTransactionAllowed(true);
}
public DataSourceTransactionManager(DataSource dataSource) {
this();
this.setDataSource(dataSource);
this.afterPropertiesSet();
}
public void setDataSource(@Nullable DataSource dataSource) {
public void setEnforceReadOnly(boolean enforceReadOnly) {
public DataSource getDataSource() {
public Object getResourceFactory() {
public boolean isEnforceReadOnly() {
public void afterPropertiesSet() {
protected DataSource obtainDataSource() {
protected Object doGetTransaction() {
protected void doBegin(Object transaction, TransactionDefinition definition) {
protected void doCommit(DefaultTransactionStatus status) {
protected void doRollback(DefaultTransactionStatus status) {
protected Object doSuspend(Object transaction) {
protected void doResume(@Nullable Object transaction, Object suspendedResources) {
protected boolean isExistingTransaction(Object transaction) {
protected void doSetRollbackOnly(DefaultTransactionStatus status) {
protected void doCleanupAfterCompletion(Object transaction) {
protected void prepareTransactionalConnection(Connection con, TransactionDefinition definition) throws SQLException {
protected RuntimeException translateException(String task, SQLException ex) {
*********
内部类:DataSourceTransactionObject
private static class DataSourceTransactionObject extends JdbcTransactionObjectSupport {
private boolean newConnectionHolder;
private boolean mustRestoreAutoCommit;
private DataSourceTransactionObject() {
}
public void setRollbackOnly() {
public void setMustRestoreAutoCommit(boolean mustRestoreAutoCommit) {
public void setConnectionHolder(@Nullable ConnectionHolder connectionHolder, boolean newConnectionHolder) {
public boolean isRollbackOnly() {
public boolean isNewConnectionHolder() {
public boolean isMustRestoreAutoCommit() {
public void flush() {
JdbcTransactionManager
public class JdbcTransactionManager extends DataSourceTransactionManager {
private static final boolean shouldIgnoreXml = SpringProperties.getFlag("spring.xml.ignore");
@Nullable
private volatile SQLExceptionTranslator exceptionTranslator;
private boolean lazyInit;
public JdbcTransactionManager() {
this.lazyInit = true;
}
public JdbcTransactionManager(DataSource dataSource) {
this();
this.setDataSource(dataSource);
this.afterPropertiesSet();
}
public void setLazyInit(boolean lazyInit) {
public void setDatabaseProductName(String dbName) {
public void setExceptionTranslator(SQLExceptionTranslator exceptionTranslator) {
public boolean isLazyInit() {
public void afterPropertiesSet() {
public SQLExceptionTranslator getExceptionTranslator() {
protected RuntimeException translateException(String task, SQLException ex) {