程序是否支持事务的先决条件是数据库,比如使用MySQL的话,如果选择的是innodb,那么支持事务,如果选择的是myisam,那么从根上就不支持事务了
MySQL怎么保证原子性?
如果要保证原子性,就需要在发生异常时,对已经执行的操作进行回滚,在MySQL中,恢复机制是通过回滚日志实现的,所有事务进行的修改,都会先记录到这个回滚日志中,然后再执行相关的操作。
如果在执行过程中遇到异常,我们直接利用回滚日志中的信息将数据回滚到修改之前的样子即可,并且回滚日志会先将数据持久化到磁盘上,这样就可以保证即便在遇到数据库突然宕机,当用户再次重启数据库时,数据库还是能够通过查回滚日志来回滚之前未完成的事务。
通过TransactionTemplate或者TransactionManager手动管理事务,在实际应用中却很少使用,下面通过代码来演示,使用TransactionTemplate进行编程式事务管理
@Autowired
private TransactionTemplate transactionTemplate;
public void testTransactionTemplate() {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(final TransactionStatus transactionStatus) {
try {
//TODO 业务代码
} catch (final Exception e) {
// 异常时回滚
transactionStatus.setRollbackOnly();
}
}
});
}
使用TransactionManager进行编程式事务管理
@Resource
private PlatformTransactionManager transactionManager;
public void testTransactionManager() {
final TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
try {
//TODO 业务代码
transactionManager.commit(status);
} catch (final Exception e) {
// 异常时回滚
transactionManager.rollback(status);
}
}
声明式事务管理,实际上是通过AOP实现,基于@Transactional的注解使用最多
@Transactional
public void testTransactional() {
userInfoDao.save(userInfo);
userInfoDetailDao.save(userInfoDetail);
}
在实际的业务开发中,大家一般使用@Transactional注解来开启事务,但很多人并不是很清楚这个注解中的参数是什么意思?有什么用?
@Transactional注解源码如下,里面包含了基本事务属性的配置:
package org.springframework.transaction.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@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 -1;
boolean readOnly() default false;
Class extends Throwable>[] rollbackFor() default {};
String[] rollbackForClassName() default {};
Class extends Throwable>[] noRollbackFor() default {};
String[] noRollbackForClassName() default {};
}
@Transactional 的常用参数介绍
属性名 | 说明 |
propagation | 事务的传播行为,默认值为 REQUIRED |
isolation | 事务的隔离级别,默认值采用 DEFAULT |
timeout | 事务的超时时间,默认值为-1(不会超时),如果超过该时间限制但事务还没有完成,则自动回滚事务 |
readOnly | 指定事务是否为只读事务,默认值为 false |
rollbackFor | 用于指定能够触发事务回滚的异常类型,并且可以指定多个异常类型 |
关于传播行为propagation属性: