mysql事务传播属性_事务整理

一:什么是事务?

答:事务是访问数据库的一个操作序列,DB(数据库)应用系统通过事务集来完成对数据的存取。

二:事务必须遵循4个原则,即常说的 ACID

A,Automicity,原子性,即事务要么被全部执行,要么被全部不执行。如果事务下的子事务全部提交成功,则所有数据库操作被提交,否则,应进行事务回滚。

C,Consistency,一致性,即状态转换必须是由一种正确的状态转换到另外一种正确的状态。

I,Isolation,隔离性,即相互间必须不能被影响。

D,Durabillity,持久性,即事务提交后将被永久保存,即便出现其他故障,事务处理结果也应得到保存。

三:事务的隔离级别(由高到低)

1:串行化,Serializable,一个事务在执行过程中完全看不到其他事务对数据库所做的更新。

2:可重复读,Repeatable Read,一个事务在执行过程中可以看到其他事务已经提交的记录,但是不能看到其他事务对已有记录的更新。

3:读已提交数据,Read Commited,一个事务在执行过程中可以看到其他事务已经提交的记录,而且能看到其他事务对已有记录的更新。

4:读未提交数据,Read UnCommited,一个事务在执行过程中可以看到其他事务没有提交的记录,而且能看到其他事务没有提交的记录的更新

1.Serializable是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。

2.Repeatable read重复读,就是在开始读取数据(事务开启)时,不再允许修改(update)操作

事例:程序员去刷信用卡(卡里有3.6万),当他买单时(事务开启,不允许其他事务的UPDATE修改操作),收费系统事先检测到他的卡里有3.6万。这个时候他的妻子不能转出金额了。接下来收费系统就可以扣款了。(事物开启,只能他消费,他妻子不能操作)

分析:重复读可以解决不可重复读问题。可重复读对应的是修改,即UPDATE操作。但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作,而不是UPDATE操作。

什么时候会出现幻读?

事例:程序员某一天去消费,花了2千元,然后他的妻子去查看他今天的消费记录(全表扫描FTS,妻子事务开启),看到确实是花了2千元,就在这个时候,程序员花了1万买了一部电脑,即新增INSERT了一条消费记录,并提交。当妻子打印程序员的消费记录清单时(妻子事务提交),发现花了1.2万元,似乎出现了幻觉,这就是幻读。

3.Read committed读提交,就是一个事务要等另一个事务提交后才能读取数据。

事例:程序员去刷信用卡(卡里有3.6万),当他买单时(程序员事务开启),收费系统事先检测到他的卡里有3.6万,就在这个时候!!

程序员的妻子要把钱全部转出充当家用,并提交。当收费系统准备扣款时,再检测卡里的金额,发现已经没钱了

(第二次检测金额当然要等待妻子转出金额事务提交完)。程序员就会很郁闷,明明卡里是有钱的…

分析:这就是读提交,若有事务对数据进行更新(UPDATE)操作时,读操作事务要等待这个更新操作事务提交后才能读取数据,可以解决脏读问题。但在这个事例中,出现了一个事务范围内两个相同的查询却返回了不同数据,这就是不可重复读。

4.Read uncommitted读未提交,就是一个事务可以读取另一个未提交事务的数据。

事例:老板要给程序员发工资,程序员的工资是3.6万/月。但是发工资时老板不小心按错了数字,按成3.9万/月,该钱已经打到程序员的户口,但是事务还没有提交,就在这时,程序员去查看自己这个月的工资,发现比往常多了3千元,以为涨工资了非常高兴。但是老板及时发现了不对,马上回滚差点就提交了的事务,将数字改成3.6万再提交。

分析:实际程序员这个月的工资还是3.6万,但是程序员看到的是3.9万。他看到的是老板还没提交事务时的数据。这就是脏读。

四:事物的传播属性

Spring提供了一个bean ——TransactionAttributSource,通过配置其事务(传播)属性(transactionattribute)来达到精确控制事务行为的目的

1.Required -- 必须的

2.Mandatory -- 强制的

3.RequiresNew -- 需要新的

4.Supports -- 支持

5.NotSupported -- 不支持

6.Never -- 从不

7.PROPAGATION_NESTED(propagation_nested) -- 用于实现真正的嵌套事务,前提条件是外部环境必须提供相应的实现支持。尽管可以通过配置的方式在bean(类)级别指定事务属性,一般来说,还是应该将事务属性应用于方法级别。为整个bean配置某个事务属性意味着其内部所有的方法都采用它,而方法级别的事务属性可以将其覆盖。

(1)Required属性告诉容器某个特定的方法需要一个事务,如果上下文中已经存在事务,则加入这个事物;否则,开启一个事务。这是一种使用最频繁的事务属性,适用于大多数情况;

(2)Mandatory属性告诉容器某个特定的方法需要一个事务。但是,不同于Required属性,它无论如何都不会开启新的事务;相反的,它会“强制”要求该方法被调用时上下文中必须存在事务,否则会抛出TransactionRequiredException异常,提示需要一个事务但没有找到。

(3)RequiresNew属性告诉容器某个特定的方法需要一个新事务的支持。如果上下文中已经存在事务A,则该事务A挂起,并启动一个新的事务B。当事务B结束后,事务A被唤醒并继续执行。事实上,使用RequiresNew违反了事务的ACID原则,因为新事务会导致原有事务的挂起。该属性在某个行为必须被完成(提交或回滚)而不受外部事务结果影响时十分有用。

例如记录日志。大多数交易系统的每一个操作都必须写进日志,无论其执行结果如何(成功或失败)。

假设某个股票交易的方法placement()启动了一个事务,并且调用了一个通用的方法audit()来记录日志。由于audit()和placement()处于同一个事务的管辖范围之内,因此一旦placement()回滚,audit()记录的日志也会相应的进行回滚;

这就违背了“任何成功或失败的操作都必须记录日志”这一业务逻辑。

这个时候,如果将audit()的事务属性设作RequiresNew,

则确保了audit()在一个新的、单独的事务中记录日志,因此不受placement()中外部事务的影响。

(4)Supports属性告诉容器,该方法不需要事务支持,但如果当前上下文中已经存在了一个事务,则加入其中。

Supports这是一个相当强大、相当有用的事务属性。

考虑这样一个场景,业务方法A用来查询某个交易者特定时期的交易总量。由于是查询操作,因此这个时候事务并不是必须的,因此我们将其事务属性设为Supports,来告诉容器在调用方法时不要开启新的事务。

但是,如果方法A被某个已经存在事务控制的方法B所调用,那么它就会加入当前事务;

那么,在该事务提交之前,方法B中对数据的任何修改对于方法A来说,都是可见的。

例如(Supports):假设某位交易者一天的最大交易额是一百万,如果采用Supports作为事务属性,一次超额交易的具体处理流程如下:

目前为止,当天总共的交易量是900,000

事务启动

交易者又进行了一笔200,000的交易

调用事务属性为Supports的查询方法,因为是同一个事务,因此得到结果为1,100,000

业务逻辑判断,已经超过最大交易限额,抛出异常,事务回滚

(5)NotSupported,我们不会得到任何异常,因为查询方法不会加入当前事务,因此它看不见当前事务中对数据库的任何修改。

目前为止,当天总共的交易量是900,000

事务启动

交易者又进行了一笔200,000的交易

调用事务属性为Notupported的查询方法,因为不属于当前事务,因此得到结果为900,000

业务逻辑判断,没有超过最大交易限额,事务提交(实际已超过当天限额)

NotSupported属性告诉容器,该方法不需要事务支持;如果当前上下文中已经存在事务,则该事务被挂起直到该方法执行完毕。

如果当前上下文中不存在事务,该方法则在没有事务支持的环境下执行。NotSupported适用于“某些方法在事务控制下有较大可能性会产生异常”的场合。

例如在XA架构的事务处理过程中,调用包含DDL语句的存储过程往往会抛出异常,因此比较好的做法是将其设为NotSupported,暂时挂起当前事务。

(6)Never属性告诉容器,该方法必须在无事务的上下文中运行。

注意,这与NotSupported不同,后者意味着,如果上下文中存在事务,则将该事务暂时挂起并在无事务的上下文中运行。但Never却不同,如果当前上下文中已经存在事务,则在调用该方法时会抛出一个异常,提示该方法不能在事务环境下运行。因为使用Never会导致各种意料之外的运行时异常,因此除非必要,一般不推荐使用

五:易混淆的传播属性

(1)Required vs. Mandatory

Required和Mandatory是两个往往容易被混淆的事务属性。

两者都可以运行在事务上下文环境中,但当上下文中不存在事务时,Required会自己开启一个事务,而Mandatory则不会。

如果某一方法需要运行在具备事务的环境,但其本身又不负责事务的控制(回滚),则该方法应该标志为Mandatory。

(2)Nested vs. RequiresNew vs. Required

另外两个比较容易的事务属性是Spring提供的Nested与RequiresNew。

如果当前上下文中存在事务,两者都是启动一个新的事务;如果当前上下文中不存在事务,则类似于PROPAGATION_REQUIRED,两者也都新建一个事务。

(3) PROPAGATION_REQUIRES_NEW 启动一个新的, 不依赖于环境的 "内部" 事务. 这个事务将被完全 commited 或rolled back 而不依赖于外部事务, 它拥有自己的隔离范围, 自己的锁, 等等。当内部事务开始执行时, 外部事务将被挂起,内务事务结束时, 外部事务将继续执行。

(4)PROPAGATION_NESTED 开始一个 "嵌套的" 事务, 它是已经存在事务的一个真正的子事务。

嵌套事务开始执行时, 它将取得一个 savepoint。如果这个嵌套事务失败, 我们将回滚到此savepoint。嵌套事务是外部事务的一部分, 只有外部事务结束后它才会被提交。

(六)传播属性概念的说明

我们一般都是将事务设置在Service层 那么当我们调用Service层的一个方法的时候它能够保证我们的这个方法中执行的所有的对数据库的更新操作保持在一个事务中,

在事务层里面调用的这些方法要么全部成功,要么全部失败。

如果你在你的Service层的这个方法中,除了调用了Dao层的方法之外,还调用了本类的其他的Service方法,这个事务是怎么规定的呢。

我必须保证我在我方法里调用的这个方法与我本身的方法处在同一个事务中,否则无法保证事物的一致性。

事务的传播特性就是解决这个问题的,“事务是会传播的”在Spring中有针对传播特性的多种配置我们大多数情况下只用其中的一种:PROPGATION_REQUIRED:

这个配置项的意思是说当我调用service层的方法的时候开启一个事务(具体调用那一层的方法开始创建事务,要看你的aop的配置),

那么在调用这个service层里面的其他的方法的时候,如果当前方法产生了事务就用当前方法产生的事务,否则就创建一个新的事务。

这个工作使由Spring来帮助我们完成的。

扩展:spring中的容器指的是什么

Spring容器可以帮助管理所有的Bean对象,专业术语称之为IoC控制反转。

在传统的程序中,对象的生成都是由开发者完成的。而在控制反转中,对象的生成全部都交给框架完成。这样的好处就是减少了程序的依赖性。

Spring帮助我们完成配置事物,就可以让我们更加的专注于我们的业务逻辑。而不用去关心事务的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL事务传播机制是用来决定事务在不同的操作中如何传播和影响的规则MySQL支持以下几种事务传播机制: 1. 作为默认的传播机制,MySQL使用的是REPEATABLE READ(可重复读)级别。在该级别下,事务开始时会创建一个快照,事务中的查询都会使用该快照作为读取数据的基础。这意味着在事务中,无论其他事务是否对数据进行了修改,读取的数据都是一致的。 2. READ COMMITTED(已提交读)是另一种常用的传播机制。在该级别下,事务中的查询会读取到其他已提交事务所做的修改,而不是使用快照。这意味着同一事务内的两个查询可能会返回不一致的结果。 3. READ UNCOMMITTED(未提交读)是最低级别的传播机制。在该级别下,事务中的查询会读取到其他未提交事务所做的修改。这可能导致脏读(读取到未提交的数据)和不可重复读(同一查询返回不同结果)。 4. SERIALIZABLE(可串行化)是最高级别的传播机制。在该级别下,事务串行执行,确保每个事务都感知到其他事务所做的修改。这种级别保证了最高的数据一致性,但也会带来性能损耗。 要设置事务传播机制,可以使用以下语句: ``` SET TRANSACTION ISOLATION LEVEL <level>; ``` 其中,<level>可以是上述提到的几种传播机制之一。 需要注意的是,不同的数据库管理系统可能对事务传播机制有所不同,以上是MySQL传播机制示例。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值