SpringBoot 事务管理@Transactional (六)

SpringBoot提供了非常方便的事务操作,通过注解就可以实现事务的回滚,非常方便快捷.

1. 事务说明

在Spring中,事务有两种实现方式,分别是编程式事务管理和声明式事务管理两种方式。 
编程式事务管理: 编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。 
声明式事务管理: 建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。 
声明式事务管理不需要入侵代码,通过@Transactional就可以进行事务操作,更快捷而且简单。推荐使用

2. 如何使用

  案例: 用户之间的转账功能实现

/**
 * 账户类
 * 
 * @author Administrator
 * id 编号 name用户名 balance余额
 *
 */
@Entity
@Table(name = "t_account")
public class Account {

	@Id
	@GeneratedValue
	private int id;
	@Column(length = 50)
	private String name;
	private float balance;....}
/**
 * 底层数据必须继承JpaRepository接口
 * @author Administrator
 *
 */
public interface AccountDao extends JpaRepository<Account, Integer> {}
启动工程,效果如下:


添加数据:

/**
 * 业务接口
 * 
 * @author Administrator
 *
 */
public interface AccountService {
	/**
	 * 转账功能
	 * 
	 * @param fromId
	 * @param toId
	 * @param money
	 */
	public void txAccount(int fromId, int toId, float money);
}

    所有service方法都加上事务操作;用来保证一致性,即service方法里的多个dao操作,要么同时成功,要么同时失败;

只需要在service方法增加注解@Transactional,无需任何配置。

/**
 * 业务类
 * @author Administrator
 *
 */
@Service("service")
public class ServiceAccountImpl implements AccountService {
	
	//注入dao
	@Autowired
	private AccountDao accountDao;

	/**
	 * 实现这个方法
	 */
	@Override
	@Transactional  //事务
	public void txAccount(int fromId, int toId, float money) {
		//根据ID查找这个用户
		Account fromAccount=accountDao.getOne(fromId);
		//重新设置余额的值
		fromAccount.setBalance(fromAccount.getBalance()-money);
		//添加数据
		accountDao.save(fromAccount);
		
		
		//根据ID查找这个用户
		Account toAccount=accountDao.getOne(toId);
		//重新设置余额的值
		toAccount.setBalance(toAccount.getBalance()+money);

		//添加数据
		accountDao.save(toAccount);
		
	}

}
/**
 * 账户Controoler类
 * 
 * @author Administrator
 *
 */
@RestController
@RequestMapping("/account")
public class AccountController {

	@Autowired
	private AccountService service;

	/**
	 * 执行
	 * 
	 * @return
	 */
	@RequestMapping("/show")
	public String show() {
		try {
			service.txAccount(1, 2, 300);// 调用业务方法
			return "ok";
		} catch (Exception e) {
			return "no";
		}

	}

}

@Transactional可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。

  1. 通过@Transactional,实现了事务操作。
  2. Spring的AOP即声明式事务管理默认是针对unchecked exception回滚。也就是默认对RuntimeException()异常或是其子类进行事务回滚;checked异常,即Exception可try{}捕获的不会回滚,因此对于我们自定义异常,通过rollbackFor进行设定,后续会单独讲
  3. 如果我们需要捕获异常后,同时进行回滚,通过TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();进行手动回滚操作。
  4. 使用Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint(); 
    设置回滚点,使用TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);回滚到savePoint。

3.常用配置

参 数 名 称功 能 描 述
readOnly该属性用于设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false。例如:@Transactional(readOnly=true)
rollbackFor该属性用于设置需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则进行事务回滚。例如:指定单一异常类:@Transactional(rollbackFor=RuntimeException.class)指定多个异常类:@Transactional(rollbackFor={RuntimeException.class, Exception.class})
rollbackForClassName该属性用于设置需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,则进行事务回滚。例如:指定单一异常类名称@Transactional(rollbackForClassName=”RuntimeException”)指定多个异常类名称:@Transactional(rollbackForClassName={“RuntimeException”,”Exception”})
noRollbackFor该属性用于设置不需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,不进行事务回滚。例如:指定单一异常类:@Transactional(noRollbackFor=RuntimeException.class)指定多个异常类:@Transactional(noRollbackFor={RuntimeException.class, Exception.class})
noRollbackForClassName该属性用于设置不需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,不进行事务回滚。例如:指定单一异常类名称:@Transactional(noRollbackForClassName=”RuntimeException”)指定多个异常类名称:@Transactional(noRollbackForClassName={“RuntimeException”,”Exception”})
propagation该属性用于设置事务的传播行为。例如:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
isolation该属性用于设置底层数据库的事务隔离级别,事务隔离级别用于处理多事务并发的情况,通常使用数据库的默认隔离级别即可,基本不需要进行设置
timeout该属性用于设置事务的超时秒数,默认值为-1表示永不超时

效果:

(1)启动工程


数据发生变化




(2)重新启动工程



数据发生变化,熊大值发生变化了,而吉吉国王没有发生变化,这样数据就不一致了!



(3)再重新启动工程



数据没有发生变化!回滚了数据!




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值