事物

事务隔离级别
隔离级别是指若干个并发的事务之间的隔离程度。
TransactionDefinition 接口中定义了五个表示隔离级别的常量:

>>>>> TransactionDefinition.ISOLATION_DEFAULT:
这是默认值,表示使用底层数据库的默认隔离级别。对大部分数据库而言,
通常这值就是TransactionDefinition.ISOLATION_READ_COMMITTED。

>>>>> TransactionDefinition.ISOLATION_READ_UNCOMMITTED:
该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据。
该级别不能防止脏读和不可重复读,因此很少使用该隔离级别(无锁)。

>>>>> TransactionDefinition.ISOLATION_READ_COMMITTED:
该隔离级别表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读,
这也是大多数情况下的推荐值(行锁:写锁保持,无读锁)。

>>>>> TransactionDefinition.ISOLATION_REPEATABLE_READ:
该隔离级别表示一个事务在整个过程中可以多次重复执行某个查询,
并且每次返回的记录都相同。即使在多次查询之间有新增的数据满足该查询,
这些新增的记录也会被忽略。该级别可以防止脏读和不可重复读(行锁:读锁保持)。

>>>>> TransactionDefinition.ISOLATION_SERIALIZABLE:
所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。
但是这将严重影响程序的性能。通常情况下也不会用到该级别(表锁)。


脏读:读取了未提交的数据,解决方法:写入时不直接写入数据库

不可重复读:一个事务2次查询同一记录,返回结果不同; 原因:有写锁(行)无读锁(行),解决方法:加入读锁(行)

幻读:一个事务中2次范围查询,获得的记录数不同(有新行加入) 原因:无范围读写锁(表锁) 解决方法:加入表锁


事务传播行为
所谓事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。
在TransactionDefinition定义中包括了如下几个表示传播行为的常量:
>>>>> TransactionDefinition.PROPAGATION_REQUIRED:
如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
>>>>> TransactionDefinition.PROPAGATION_REQUIRES_NEW:
创建一个新的事务,如果当前存在事务,则把当前事务挂起。
>>>>> TransactionDefinition.PROPAGATION_SUPPORTS:
如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
>>>>> TransactionDefinition.PROPAGATION_NOT_SUPPORTED:
以非事务方式运行,如果当前存在事务,则把当前事务挂起。
>>>>> TransactionDefinition.PROPAGATION_NEVER:
以非事务方式运行,如果当前存在事务,则抛出异常。
>>>>> TransactionDefinition.PROPAGATION_MANDATORY:
如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
>>>>> TransactionDefinition.PROPAGATION_NESTED:
如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,
则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。


这里需要指出的是,前面的六种事务传播行为是 Spring 从 EJB 中引入的,他们共享相同的概念。而 PROPAGATION_NESTED是 Spring 所特有的。
以 PROPAGATION_NESTED 启动的事务内嵌于外部事务中(如果存在外部事务的话),此时,内嵌事务并不是一个独立的事务,
它依赖于外部事务的存在,只有通过外部的事务提交,才能引起内部事务的提交,嵌套的子事务不能单独提交。
如果熟悉 JDBC 中的保存点(SavePoint)的概念,那嵌套事务就很容易理解了,其实嵌套的子事务就是保存点的一个应用,
一个事务中可以包括多个保存点,每一个嵌套子事务。另外,外部事务的回滚也会导致嵌套子事务的回滚。


事务超时
所谓事务超时,就是指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。
在 TransactionDefinition 中以 int 的值来表示超时时间,其单位是秒。
事务的只读属性
事务的只读属性是指,对事务性资源进行只读操作或者是读写操作。所谓事务性资源就是指那些被事务管理的资源,
比如数据源、 JMS 资源,以及自定义的事务性资源等等。如果确定只对事务性资源进行只读操作,那么我们可以将事务标志为只读的,
以提高事务处理的性能。在 TransactionDefinition 中以 boolean 类型来表示该事务是否只读。
事务的回滚规则
通常情况下,如果在事务中抛出了未检查异常(继承自 RuntimeException 的异常),
则默认将回滚事务。如果没有抛出任何异常,或者抛出了已检查异常,则仍然提交事务。
这通常也是大多数开发者希望的处理方式,也是 EJB 中的默认处理方式。但是,
我们可以根据需要人为控制事务在抛出某些未检查异常时任然提交事务,或者在抛出某些已检查异常时回滚事务。


传播行为 [,隔离级别] [,只读属性] [,超时属性] [不影响提交的异常] [,导致回滚的异常]
>>>>> 传播行为是唯一必须设置的属性,其他都可以忽略,Spring为我们提供了合理的默认值。
>>>>> 传播行为的取值必须以“PROPAGATION_”开头,
具体包括:PROPAGATION_MANDATORY、 PROPAGATION_NESTED、PROPAGATION_NEVER、PROPAGATION_NOT_SUPPORTED、 
PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、PROPAGATION_SUPPORTS,共七种取值。
>>>>> 隔离级别的取值必须以“ISOLATION_”开头,
具体包括:ISOLATION_DEFAULT、 ISOLATION_READ_COMMITTED、ISOLATION_READ_UNCOMMITTED、 
ISOLATION_REPEATABLE_READ、ISOLATION_SERIALIZABLE,共五种取值。
>>>>> 如果事务是只读的,那么我们可以指定只读属性,使用“readOnly”指定。否则我们不需要设置该属性。
>>>>> 超时属性的取值必须以“TIMEOUT_”开头,后面跟一个int类型的值,表示超时时间,单位是秒。
>>>>> 不影响提交的异常是指,即使事务中抛出了这些类型的异常,事务任然正常提交。必须在每一个异常的名字前面加上“+”。

异常的名字可以是类名的一部分。比如“+RuntimeException”、“+tion”等等。


事物嵌套和新启一个事物 PROPAGATION_NESTED PROPAGATION_REQUIRES_NEW 配置  必须在两个不同的service中才能
生效 如果在同一个service中  会默认 按 PROPAGATION_REQUIRED 继承上一个事物运行 而不是嵌套和新启。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值