事务(Transactional):
在软件开发领域,全有或全无的操作被称作事务,事务具有四个特性:ACID。
A:Atomic 原子性 确保事务中的所有操作全部发生或全部不发生
C:Consistent 一致性 事务的执行结果是确定
I:Isolated 隔离性 事务是彼此隔离的,避免同步读写相同数据
D:Durable 持久性 事务的结果是持久化的
Spring提供的事务管理器:
DataSourceTransactionManager 用于对jdbc和ibatis进行持久化的场景,实现了PlatformTransactionManager接口
利用IOC实例化配置如下:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
事务属性:
1、传播行为:定义了何时要创建一个事务或何时使用已有的事务;
2、隔离级别:定义了一个事务可能受其他并发事务影响的程度;
3、回滚规则:定义什么异常下回滚
4、事务超时:自动回滚时间
5、是否只读:对读数据库操作加声明,系统就会对该操作优化
Spring中声明事务的注解如下:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
// 事务名
String value() default "";
// 事务传播行为
Propagation propagation() default Propagation.REQUIRED;
// 隔离级别
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 {};
}
<tx:annotation-driven transaction-manager="transactionManager"/>
上面的配置告诉Spring检查上下文中所有的Bean并查找使用@Transactional注解的Bean,不论注解级别是用在类级别上还是方法级别上,
找到Bean后会自动为它添加事务通知。
事务拦截器(AOP)
TransactionInterceptor调用invoke(final MethodInvocation invocation)进行事务处理
public Object invoke(final MethodInvocation invocation) throws Throwable {
// Work out the target class: may be <code>null</code>.
// The TransactionAttributeSource should be passed the target class
// as well as the method, which may be from an interface.
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
// If the transaction attribute is null, the method is non-transactional.
final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(invocation.getMethod(), targetClass);
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
final String joinpointIdentification = methodIdentification(invocation.getMethod(), targetClass);
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
// Standard transaction demarcation with getTransaction and commit/rollback calls.
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal = null;
try {
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
retVal = invocation.proceed();
}
catch (Throwable ex) {
// target invocation exception
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
commitTransactionAfterReturning(txInfo);
return retVal;
}
else {
// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
try {
Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr,
// 事务回调函数
new TransactionCallback<Object>() {
public Object doInTransaction(TransactionStatus status) {
TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
try {
return invocation.proceed();
}
catch (Throwable ex) {
// 判断是否是需要回滚的异常类型
if (txAttr.rollbackOn(ex)) {
// A RuntimeException: will lead to a rollback.
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
else {
throw new ThrowableHolderException(ex);
}
}
else {
// 否则事务正常提交
// A normal return value: will lead to a commit.
return new ThrowableHolder(ex);
}
}
finally {
// Reset the TransactionInfo ThreadLocal.
cleanupTransactionInfo(txInfo);
}
}
});
// Check result: It might indicate a Throwable to rethrow.
if (result instanceof ThrowableHolder) {
throw ((ThrowableHolder) result).getThrowable();
}
else {
return result;
}
}
catch (ThrowableHolderException ex) {
throw ex.getCause();
}
}
}
AnnotationTransactionAttributeSource调用findTransactionAttribute(Method method)和findTransactionAttribute(Class<?> clazz)方法
获取TransactionAttribute(@Transactional注解中设置的五个事务属性参数)
类SpringTransactionAnnotationParser调用parseTransactionAnnotation方法生成TransactionAttribute(存储事务属性)
如果事务属性为空,则认为为非事务方法,直接调用原方法
CallbackPreferringPlatformTransactionManager调用execute(TransactionDefinition definition, TransactionCallback<T> callback)
TransactionCallback是处理事务的回调模板类(接口)
CallbackPreferringPlatformTransactionManager 继承自 PlatformTransactionManager
DataSourceTransactionManager实现的事务提交与回滚方法:
@Override
protected void doCommit(DefaultTransactionStatus status) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
Connection con = txObject.getConnectionHolder().getConnection();
if (status.isDebug()) {
logger.debug("Committing JDBC transaction on Connection [" + con + "]");
}
try {
con.commit();
}
catch (SQLException ex) {
throw new TransactionSystemException("Could not commit JDBC transaction", ex);
}
}
@Override
protected void doRollback(DefaultTransactionStatus status) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
Connection con = txObject.getConnectionHolder().getConnection();
if (status.isDebug()) {
logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");
}
try {
con.rollback();
}
catch (SQLException ex) {
throw new TransactionSystemException("Could not roll back JDBC transaction", ex);
}
}
依懒接口:java.sql.Connection
Connection最终实现的类:com.mysql.jdbc.ConnectionImpl.class
利用visualvm查看JVM中的实例结果如下:
可以看出AOP代理和回调