事务
事务的特性(ACID)
原子性(Atomicity):
标识将事务中所有的操作进行捆绑层一个不可分割的单元格,
计对事务所有进行的数据库修改等操作,要么全部执行,要么就是全部失败
隔离性(Isolation):
指的是一个事务的执行,不能被其他的事务进行干扰,一个事务内部的操作以及使用的数据库对并发的其他事务都是进行隔离的,并发执行的各个事务之间是不能进行相互干扰的 事务之间隔离,互不干扰
持久性(Durability):
永久性,指一个事务提交之后,它对数据库中数据的改变应该是永久性的
一致性(Consistency):
事务前后,数据库数据完整性不被破坏,总是与预期一致的状态,就像借钱,一方借多少,另一方加多少,数据不会凭空增多,也不会凭空减少。
数据是一致且持久的,操作是原子且隔离的
事务的四种隔离级别
①read uncommitted(读未提交):事物的修改,即使没有提交,对其他事物也是可见的。事物读未提交的数据成为脏读。
②read committed(读已提交):一个事物在提交之前,所做的任何修改对其他事物都是不看见,但是对其他事物称为不可重复读,因为两次查询的结果可能不一样。
③repeatable read(可重复读):该级别解决了脏读、不可重复读的问题,保证了在一个事物中多次读到的数据是一致的,但是没有解决幻读的问题。(默认)
④serializable(串行化):事务挨个执行,避免了幻读的问题。
数据库的事务隔离越严格,并发副作用越小,但付出的代价也就越大,因为事务隔离实质上就是使事务在一定程度上 “串行化”进行,这显然与“并发”是矛盾的
同时,不同的应用对读一致性和事务隔离程度的要求也是不同的,比如许多应用对“不可重复读”和“幻读”并不敏感,可能更关心数据并发访问的能力。
主流数据库默认的事务隔离级别
Mysql——repeatable read(可重复读)
Oracle——read committed(读已提交)
PostGreSql——read committed(读已提交)
事务并发可能产生的问题(不考虑隔离级别)
脏读:
读到另一事务还未提交的数据。
(只有读未提交隔离级别才会出现这种问题 。 eg:A对数据减10但还未提交,B读取到的数据数据已经少了10)
不可重复度:
一个事务多次对相同的数据读取可能会出现不同的结果
(读未提交和读已提交的隔离级别下都可能会出现不可重复读的问题,关键在于重复读取的数据同时在被其他事务进行修改操作)
幻读/虚读:
当前事务读取数据时,读范围内的数据,被其他事务穿插有修改操作,导致出现读取幻象。
(在读未提交、读已提交和可重复读三种事务隔离级别下都可能会出现)
Spring事务
Spring管理事务的方式
- 编程式事务,在代码中硬编码。(不推荐使⽤)
- 声明式事务,在配置⽂件中配置(推荐使⽤)
- 基于XML的声明式事务
- 基于注解的声明式事务
Spring事务五种隔离级别
一种控制并发执行的事务对数据操作的规则。
TransactionDefinition 接⼝中定义了五个表示隔离级别的常量
TransactionDefinition.ISOLATION_DEFAULT: 数据库默认
使⽤后端数据库默认的隔离级别,Mysql 默认采⽤的 REPEATABLE_READ隔离级别 Oracle 默认采⽤的 READ_COMMITTED隔离级别.
TransactionDefinition.ISOLATION_READ_UNCOMMITTED: 读未提交
最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
TransactionDefinition.ISOLATION_READ_COMMITTED: 读已提交
允许读取并发事务已经提交的数据,可以阻⽌脏读,但是幻读或不可重复读仍有可能发⽣
TransactionDefinition.ISOLATION_REPEATABLE_READ: 可重复读
对同⼀字段的多次读取结果都是⼀致的,除⾮数据是被本身事务⾃⼰所修改,可以阻⽌脏读和不可重复读,但幻读仍有可能发⽣。
TransactionDefinition.ISOLATION_SERIALIZABLE: 序列化
最⾼的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执⾏,这样事务之间就完全不可能产⽣⼲扰,也就是说,该
级别可以防⽌脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会⽤到该级别。
--参考java Guide文章
Spring事务的7种传播行为
⽀持当前事务的情况:
TransactionDefinition.PROPAGATION_REQUIRED: 存在则加入,没有就新建如果当前存在事务,则加⼊该事务;如果当前没有事务,则创建⼀个新的事务。
TransactionDefinition.PROPAGATION_SUPPORTS:存在则加入,没有则不管
如果当前存在事务,则加⼊该事务;如果当前没有事务,则以⾮事务的⽅式继续运⾏。
TransactionDefinition.PROPAGATION_MANDATORY: 存在则加入,没有就抛异常
如果当前存在事务,则加⼊该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)
不⽀持当前事务的情况:
TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建新事物,存在则挂起创建⼀个新的事务,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED:非事务运行,存在则挂起
以⾮事务⽅式运⾏,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_NEVER:非事务运行,存在则抛异常
以⾮事务⽅式运⾏,如果当前存在事务,则抛出异常。
其他情况:
TransactionDefinition.PROPAGATION_NESTED:存在则嵌套事务,没有就新建如果当前存在事务,则创建⼀个事务作为当前事务的嵌套事务来运⾏;如果当前没有事务,则该取值等价TransactionDefinition.PROPAGATION_REQUIRED。
--参考java Guide文章
Spring事务回滚rollbackFor
@Transactional(rollbackFor = Exception.class)
当 @Transactional 注解作⽤于类上时,该类的所有 public ⽅法将都具有该类型的事务属性,同时,我们也可以在⽅法级别使⽤该标注来覆盖类级别的定义。
一般用于方法级别。
如果类或者⽅法加了这个注解,那么这个类⾥⾯的⽅法抛出异常,就会回滚,数据库⾥⾯的数据也会回滚。
在 @Transactional 注解中如果不配置 rollbackFor 属性,那么事物只会在遇到 RuntimeException 的时候才会回滚,加上 rollbackFor=Exception.class ,可以让事物在遇到⾮运⾏时异常时也回滚。
标签:事务,隔离,TransactionDefinition,重复,spring,提交,级别 From: https://www.cnblogs.com/deity-night/p/17149962.html