关于事务的总结

一、什么是事务:

事务是逻辑上的一组操作,要么执行,要么不执行

二、事务的特性(ACID)

原子性:事务是最小的执行单元,不允许分割。确保事务的执行要么全部完成,要么失败。
一致性:执行事务前后,数据保持一致。数据库总是从一个一致性的状态转换到另一个一致性的状态。
隔离性:并发访问数据库时,一个用户的事务不会被其他事务所干扰,各并发事务之间的数据库是独立的。(通俗的讲,隔离性就是指控制另外一个事务可以看到本事务内的哪些数据)------ 补充说明: 通常来说,一个事务所做的修改在最终提交以前,对其他事务是不可见的。这里所说的“通常来说”是指,不同的数据库存储引擎实现会有些差异,在平衡性能和数据一致性问题上。
持久性:一个事务一旦提交。它对数据库的影响是持久的,及时数据库发生故障也不应该对其有任何影响。

事务的ACID特性
隔离级别

隔离级别其实比想象的要复杂,在SQL标准中定义了四种隔离级别,每一种级别都规定了,一个事务中所做的修改,哪些在事务内和事务间是可见的,哪些是不可见的。(较低级别的隔离通常可以执行更高的并发,系统的开销也更低,其实隔离级别的选择,就是在平衡数据一致性和并发性能)

四种隔离级别:

READ UNCOMMITTED (未提交读)
   在READ UNCOMMITTED 级别,事务中的修改,即使没有提交,对其他事务也都是可见的。事务可以读取未提交的数据,这也被称为脏读。 这个级别会导致很多问题(在实际应用中一般很少使用)
READ COMMITED (提交读) 
   大多数数据库系统的默认隔离级别都是这个(但是MySQL 不是),READ COMMITED 满足前面提到的隔离性的简单定义:一个事务开始时,只能“看见”已经提交的事务所做的修改,换句话说,一个事务开始直到提交之前,所做的任何修改对其他事务都是不可见的。所以,这个级别有时候也会被称为不可重复读。(注:这里的不可重复读指的是对同一记录数据的读取,多次读取可能会出现不相同的情况,比如第一次读取在另一个事务提交之前,第二次读取是在另一个事务提交之后,如果另一个事务对该记录进行了修改操作,则会出现两次读取数据不一样的情况)
REPEATABLE READ(可重复读)  ——— MqSQL默认的隔离级别
   REPEATABLE READ 解决了脏读的问题,该级别保证了在同一个事务中多次读取相同记录的结果是一致的,也就是避免了不可重复读问题。(注意这里所说的多次读取相记录的结果是一致,也就是说,即使另一个事务对该相同记录进行了修改并提交,当前事务也不能读取到另一个事务的修改结果。如果需要在事务中读取到最新的数据,则可以加上for update);
还有一点,可重复读无法解决幻读问题。所谓幻读,指的是当某个事务在读取某个范围内的记录时,另一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行。
需要注意的是,我们在使用MySQL时,一般都是使用InnoDB作为存储引擎,在InnoDB内,通过多版本并发控制(MVCC)解决了幻读的问题。
**SERIALIZABLE(可串行化)**
    可串行化作为最高的隔离级别。它通过强制事务串行执行,实际应用中也很少用到这个

所以总结来说
MySQL + InnoDB 同时解决了隔离性导致的脏读,不可重复读和幻读问题。
注:InnoDB,所有的操作都是事务。
隔离级别。

事务隔离级别

三、Spring的事务管理接口:

PlatformTransactionManager: (平台)事务管理器
TransactionDefinition: 事务定义信息(事务隔离级别、传播行为、超时、只读、回滚规则)
TransactionStatus: 事务运行状态

所谓事务管理,就是按照给定的事务规则来提交或者回滚操作
Spring并不直接管理事务,而是提供了多种事务管理器,他们将具体的事务管理委托给了第三方持久化框架平台,比如JDBC,Mybatis, JTA

那什么是事务属性呢?
事务属性可以理解成事务的一些基本配置,描述了事务策略如何应用到方法上。事务属性包含了5个方面。
事务属性

1、 事务只读属性(对事物资源是否执行只读操作)
如果事务内只涉及读或者读写操作,可将事务设置为只读事务,这样可以提高性能(为什么能提高性能?)

2、事务的传播行为:(Spring为了解决业务层方法之间相互调用的事务问题)
当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。在TransactionDefinition定义中包括了如下几个表示传播行为的常量:

支持当前事务的情况:
TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
TransactionDefinition.PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
不支持当前事务的情况:
TransactionDefinition.PROPAGATION_REQUIRES_NEW: 创建一个新的事务,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED: 以非事务方式运行,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_NEVER: 以非事务方式运行,如果当前存在事务,则抛出异常。
其他情况:
TransactionDefinition.PROPAGATION_NESTED: 如果当前存在事务,则创建一个事务 
   作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于 
补充
TransactionDefinition.PROPAGATION_REQUIRED。
    这里需要指出的是,前面的六种事务传播行为是 Spring 从 EJB 中引入的,他们共享相同的概念。而 PROPAGATION_NESTED 是 Spring 所特有的。以 PROPAGATION_NESTED 启动的事务内嵌于外部事务中(如果存在外部事务的话),此时,内嵌事务并不是一个独立的事务,它依赖于外部事务的存在,只有通过外部的事务提交,才能引起内部事务的提交,嵌套的子事务不能单独提交。如果熟悉 JDBC 中的保存点(SavePoint)的概念,那嵌套事务就很容易理解了,其实嵌套的子事务就是保存点的一个应用,一个事务中可以包括多个保存点,每一个嵌套子事务。另外,外部事务的回滚也会导致嵌套子事务的回滚。

3、事务超时属性(一个事务允许执行的最长时间)
所谓事务超时,就是指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。在 TransactionDefinition 中以 int 的值来表示超时时间,其单位是秒。

4、回滚规则(定义事务回滚规则)
这些规则定义了哪些异常会导致事务回滚而哪些不会。默认情况下,事务只有遇到运行期异常时才会回滚(注意如果将runtime异常catch住了,也会导致事务不回滚),而在遇到检查型异常时不会回滚。但是你可以声明事务在遇到特定的检查型异常时像遇到运行期异常那样回滚。同样,你还可以声明事务遇到特定的异常不回滚,即使这些异常是运行期异常。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容