Spring boot transaction 事务

什么是事务?

指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 简单的说,事务就是并发控制的单位,是用户定义的一个操作序列。 而一个逻辑工作单元要成为事务,就必须满足ACID属性。

  • 原子性(Atomicity)

    事务中的操作要么都不做,要么就全做。
    
  • 一致性(Consistency)

    事务执行的结果必须是从数据库从一个一致性状态转换到另一个一致性状态。
    
  • 隔离性(Isolation)

    一个事务的执行不能被其他事务干扰
    
  • 持久性(Durability)

    一个事务一旦提交,它对数据库中数据的改变就应该是永久性的
    

事务的隔离级别:

  • DEFAULT :这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。

  • 读未提交(Read Uncommitted)

    引发脏读(读取了未提交的数据)
    
  • 读已提交(Read Committed)

    这是大多数数据库系统默认的隔离级别,但不是MySQL默认的,只能看见已经提交事务所做的改变,
    引发不可重复读,不可重读读意味着我们同一事务执行完全相同的select语句时可能看到不一样的结果。
    ——>导致这种情况的原因可能有:(1)有一个交叉的事务有新的commit,导致了数据的改变;(2)一个数据库被多个实例操作时,同一事务的其他实例在该实例处理其间可能会有新的commit,多个commit提交时,只读一次出现结果不一致。
    
  • 可重复读(Repeatable Read)

    这是MySQL的默认事务隔离级别;
    
    它确保同一事务的多个实例在并发读取数据时,看到同样的数据行,此级别可能出现的问题--幻读(Phantom Read),当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行,InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。
    
  • 可串行化(Serializable)

    这是最高的隔离级别,
    它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。
    简言之,它在每个读的数据行上加上共享锁。
    可能导致大量的超时现象和锁竞争。
    

spring boot 事务代码示例

  • 前期各种环境准备在 上一章节

  • 本章节代码需要在上一章节基础上编写!注意哦

  • 在启动类上 @EnableTransactionManagement

@SpringBootApplication
@ComponentScan(basePackages = {
		// framework
		"com.pangugle"
})
@EnableTransactionManagement
public class App
{
    public static void main( String[] args )
    {
    	SpringApplication.run(App.class, args);
    }
}
  • 注解事务 @Transactional
@Service
public class UserServiceImpl implements UserService{

	@Autowired
	 private UserDao mUserDao;

	@Transactional(rollbackFor = {RuntimeException.class, Error.class})
	public void addUser(User user)
	{
		 mUserDao.saveUser(user);
		System.out.println("add user succes ....");
	}
}

代码说明:

  • rollbackFor:触发回滚的异常,默认是RuntimeException和Error

  • isolation: 事务的隔离级别

    默认是Isolation.DEFAULT也就是数据库自身的默认隔离级别,
    
    比如MySQL是ISOLATION_REPEATABLE_READ可重复读
    
  • controller 层调用

@RestController
public class HelloController {

	@Autowired
	private UserService mUserService;

	@RequestMapping("/sayHello")
	public String sayHello()
	{
		User user = new User();
		user.setUsername("u1");;
		user.setPassword("fasdfasdfjafsdfs");
		mUserService.addUser(user);
		return "hello spring boot!";
	}
}

浏览器访问

http://127.0.0.1:8080/sayHello

注意:

Service 层的注解使用的是 @Service

分布式事务实现方式:

分布式事务解决方案,基于CAP理论 、BASE理论、幂等性理论:

  • MQ做消息处理,MQ消息一致性。

  • 两阶段提交TCC框架、蚂蚁金服Seata、阿里GTS框架、LCN框架。

  • 将业务代码分得更细。

  • 数据事务补偿, 补偿机制 ,针对读和写操作。

最后送上:

阿里巴巴 Rocketmq 分布式事务

在一些特殊的环境下,操作数据要保证最终一致性,因此会加 zookeeper分布式锁

一般它的代码流程如下

boolean isLock = false;
try {
  isLock = zkLock.lock();
  if(isLock)
  {
    .....
  }
}
catch(Exception e)
{
  .....
}
finally
{
  if(isLock)
  {
    zkLock.unLock();
  }
}