java web 事务详解

  • 事务的ACID

答: 
- 原子性(Atomic):事务中各项操作,要么全做要么全不做,任何一项操作的失败都会导致整个事务的失败; 
- 一致性(Consistent):事务结束后系统状态是一致的; 
- 隔离性(Isolated):并发执行的事务彼此无法看到对方的中间状态; 
- 持久性(Durable):事务完成后所做的改动都会被持久化,即使发生灾难性的失败。通过日志和同步备份可以在故障发生后重建数据。

 

  • 事务并发可能引发的5类问题

脏读(Dirty Read):A事务读取B事务尚未提交的数据并在此基础上操作,而B事务执行回滚,那么A读取到的数据就是脏数据。

时间转账事务A取款事务B
T1 开始事务
T2开始事务 
T3 查询账户余额为1000元
T4 取出500元余额修改为500元
T5查询账户余额为500元(脏读) 
T6 撤销事务余额恢复为1000元
T7汇入100元把余额修改为600元 
T8提交事务 

不可重复读(Unrepeatable Read):事务A重新读取前面读取过的数据,发现该数据已经被另一个已提交的事务B修改过了。

时间转账事务A取款事务B
T1 开始事务
T2开始事务 
T3 查询账户余额为1000元
T4查询账户余额为1000元 
T5 取出100元修改余额为900元
T6 提交事务
T7查询账户余额为900元(不可重复读) 

幻读(Phantom Read):事务A重新执行一个查询,返回一系列符合查询条件的行,发现其中插入了被事务B提交的行。

时间统计金额事务A转账事务B
T1 开始事务
T2开始事务 
T3统计总存款为10000元 
T4 新增一个存款账户存入100元
T5 提交事务
T6再次统计总存款为10100元(幻读) 

第1类丢失更新:事务A撤销时,把已经提交的事务B的更新数据覆盖了。

时间取款事务A转账事务B
T1开始事务 
T2 开始事务
T3查询账户余额为1000元 
T4 查询账户余额为1000元
T5 汇入100元修改余额为1100元
T6 提交事务
T7取出100元将余额修改为900元 
T8撤销事务 
T9余额恢复为1000元(丢失更新) 

第2类丢失更新:事务A覆盖事务B已经提交的数据,造成事务B所做的操作丢失。

时间转账事务A取款事务B
T1 开始事务
T2开始事务 
T3 查询账户余额为1000元
T4查询账户余额为1000元 
T5 取出100元将余额修改为900元
T6 提交事务
T7汇入100元将余额修改为1100元 
T8提交事务 
T9查询账户余额为1100元(丢失更新) 

数据并发访问所产生的问题,在有些场景下是可能是允许的,但是有些场景下可能就是致命的,数据库通常会通过锁机制来解决数据并发访问问题,按锁定对象不同可以分为表级锁和行级锁按并发事务锁定关系可以分为共享锁和独占锁,具体的内容大家可以自行查阅资料进行了解。 
直接使用锁是非常麻烦的,为此数据库为用户提供了自动锁机制,只要用户指定会话的事务隔离级别,数据库就会通过分析SQL语句然后为事务访问的资源加上合适的锁,此外,数据库还会维护这些锁通过各种手段提高系统的性能,这些对用户来说都是透明的(就是说你不用理解,事实上我确实也不知道)。ANSI/ISO SQL 92标准定义了4个等级的事务隔离级别,如下表所示:

隔离级别脏读不可重复读幻读第一类丢失更新第二类丢失更新
READ UNCOMMITED允许允许允许不允许允许
READ COMMITTED不允许允许允许不允许允许
REPEATABLE READ不允许不允许允许不允许不允许
SERIALIZABLE不允许不允许不允许不允许不允许

 

  • 事务传播行为

      1、@Transactional(propagation=Propagation.REQUIRED
如果有事务, 那么加入事务, 没有的话新建一个(默认情况下)


     2、@Transactional(propagation=Propagation.NOT_SUPPORTED
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。


     3、@Transactional(propagation=Propagation.REQUIRES_NEW
不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务


    4、@Transactional(propagation=Propagation.MANDATORY)                                                                                                             支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。(必须在一个已有的事务中执行,否则抛出异常)


    5、@Transactional(propagation=Propagation.NEVER
以非事务方式执行,必须在一个没有的事务中执行,如果当前存在事务,否则抛出异常(与Propagation.MANDATORY相反)


    6、@Transactional(propagation=Propagation.SUPPORTS
支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。

 

     7、@Transactional(propagation=Propagation.NESTED )                                                                                                          如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作,支持当前事务,新增Savepoint点,与当前事务同步提交或回滚。 
嵌套事务一个非常重要的概念就是内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚。 

 

     PROPAGATION_NESTED 与PROPAGATION_REQUIRES_NEW的区别 
它们非常 类似,都像一个嵌套事务,如果不存在一个活动的事务,都会开启一个新的事务。使用PROPAGATION_REQUIRES_NEW时,内层事务与外层事务就像两个独立的事务一样,一旦内层事务进行了提交后,外层事务不能对其进行回滚。两个事务互不影响。两个事务不是一个真正的嵌套事务。同时它需要JTA 事务管理器的支持。 
使用PROPAGATION_NESTED时,外层事务的回滚可以引起内层事务的回滚。而内层事务的异常并不会导致外层事务的回滚,它是一个真正的嵌套事务。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
随着信息产业的不断壮大,对软件的需求也越来越多,推动了软件开发行业的迅猛发展,团体开发软件已经是非常重要的软件开发手段,为了加强团体协作的高效性和对软件开发的同步和准确性,实现对软件开发过程的有效的管理和对开发事务的有效及时的处理,就需要一款适合软件开发团队协作使用的事务跟踪和管理系统。 系统主要基于.NET Framework的体系结构,应用ASP.NET开发技术以及C#语言和ADO.NET,实现了基于ASP.NET的事务跟踪系统,首先分析了团体开发软件时的协作中碰到的同步性、时效性等问题,分析并获取了本事务跟踪系统的原始需求,在设计系统时采用了表现层USL、业务逻辑层BLL、数据访问层DAL以及数据访问层接口IDAL的三层模型,另外采用了Log4net为系统的管理并记录日志。实现了对事务的及时跟踪,使得对信息的管理更加及时、高效,提高了工作效率,该系统的主要功能的功能有人员注册、密码修改及找回,项目的创建、人员配置、人员锁定解锁,任务的创建、状态修改、任务的搜索、关注,邮件提醒,以及后台线程对数据库的操作实现历史任务信息的自动存档功能。 系统布署上线以后运行良好,经过对使用者的使用调查,加入了任务留言时邮件提醒、新增了对任务类别的管理及搜索,使得系统有更好的用户体验。 关键词:ASP.NET,ADO.NET,C#,Log4net,IDAL,事务跟踪

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值