欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

事务的基本概念

程序员文章站 2022-07-04 23:46:50
...

事务

数据库事务必须满足4个特性(ACID)

  • 原子性,事务中的指令要不都完成,要不都不完成
  • 一致性
  • 隔离性
  • 持久性

隔离性有几个等级。而数据的一致性是最终的目的。

  • 脏读:A事务读取了B事务已经更改但是没有提交的数据
  • 不可重复读:A事务读取了B事务已经更改且已经提交的数据。也就是说A事务读取了数据,然后B事务更改数据并提交,而此时A事务还没有结束,如果A事务继续读取那个数据的话,会发现两次数据不相同
  • 幻读:和上面类似,只是更改变成了新加。但是在编程上的实现肯定有很大的不同。防止不可重复读,只要让A事务对自己读取的行进行加行级别的锁就可以了。而防止幻读需要对整个表进行加锁。
  • 丢失更新 两个事物读取同一数据,然后进行不同操作,然后提交。那么,后提交的数据会把先提交的数据覆盖掉。

SQL标准制定了四种隔离级别

  • Read Uncommitted(读取未提交内容)
    简而言之,就是不做事务隔离,上面的所有问题都会发生。实际中很少使用。

  • Read Committed(读取提交内容)
    就是可以抵挡住脏读了。此时,只有事务提交后,其他事务才能看到更改

  • Repeatable Read(可重读)
    防止了不可重复读的现象,但还是允许幻读

  • Serializable(可串行化)
    强行通过对事务排序。可以杜绝一切的事务不一致问题。但是效率也是最低的

JDBC则定义五种事物隔离级别:

  • RANSACTION_NONE JDBC: 驱动不支持事务

  • TRANSACTION_READ_UNCOMMITTED 允许脏读、不可重复读和幻读,丢失更新。

  • TRANSACTION_READ_COMMITTED 禁止脏读,但允许不可重复读和幻读,丢失更新。

  • TRANSACTION_REPEATABLE_READ 禁止脏读和不可重复读,但允许幻读,丢失更新。

  • TRANSACTION_SERIALIZABLE 禁止脏读、不可重复读和幻读,丢失更新

事务传播

事物传播行为:
七个事务的传播行为

  • propagation_required 默认的Spring事务传播级别,使用该级别的特点是:如果上下文中已经存在事务,那么就加入到事务中执行;如果当前上下文中不存在事务,则新建事务执行。所以这个级别通常能满足处理大多数的业务场景。

  • propagation_supports 如果一个事务存在,则支持当前事务,如果不存在,则非事务的方法运行

  • propagation_mendatory 如果一个事务存在,则支持当前事务,如果存在,则抛出异常

  • propagation_requires_new 总是要开启一个新的事务,如果事务存在,将该事务挂起

  • propagation_not_supported 总是非事务方法运行,并挂起所有的事务

  • propagation_never 总是非事务方法运行,如果事务存在则抛出异常

  • propagation_nested 某一个事务存在,则运行在一个嵌套的事务中

java中的事务

Spring 同时支持编程式事务和声明式事务。编程式事务需要在代码中显式调用beginTransaction()、commit()、rollback()等事务管理相关的方法。Spring 的声明式事务管理在底层是建立在 AOP 的基础之上的,其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。事务增强也是AOP的一大用武之处。

因为现代架构由CS向BS架构演进,可信边界前移,所以,直接使用数据库锁机制的地方减少了。
当然,你仍然可以通过sql来使用数据库自己的锁机制

SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}

如果选择sesion参数,则本次会话所开启的事物全部使用该事务隔离级别。

如果使用global参数,则本次会话和所有新连接的会话都会使用该事务隔离级别

如果不使用任何参数,则只有本会话下一次开启的事物使用该隔离级别。

分布式事务

XA协议
分为事务协调者/事务参与者两种角色
在XA分布式事务的第一阶段,作为事务协调者的节点会首先向所有的参与者节点发送Prepare请求。
在接到Prepare请求之后,每一个参与者节点会各自执行与事务有关的数据更新,写入Undo Log和Redo Log。如果参与者执行成功,暂时不提交事务,而是向事务协调节点返回“完成”消息。
当事务协调者接到了所有参与者的返回消息,整个分布式事务将会进入第二阶段。
在XA分布式事务的第二阶段,如果事务协调节点在之前所收到都是正向返回,那么它将会向所有事务参与者发出Commit请求。
接到Commit请求之后,事务参与者节点会各自进行本地的事务提交,并释放锁资源。当本地事务完成提交后,将会向事务协调者返回“完成”消息。
当事务协调者接收到所有事务参与者的“完成”反馈,整个分布式事务完成。
详情请参考
https://blog.csdn.net/bjweimengshu/article/details/79607522