JTA之spring 整理

JTA - Java Transaction API
JTA Transaction是指由J2EE Transaction manager去管理的事务。其最大的特点是调用UserTransaction接口的begin,commit和rollback方法来完成事务范围的界定,事务的提交和回滚。
通常说到事务就离不开事务几个特性:
原子性:事务的必需提交或者回滚其中的一项操作失败都会引起事务的回滚.
一致性:不管事务是提交或者是回滚都的操作必需是完整的一致的.
隔离性:在事务操作中资源不能被其它的事务操作,如读写锁.
持久性:就是事务提交数据要持久的.如保存到硬盘上.
Spring 提供的事务管理仅仅是对现有的事务管理api进行封装.platformTracsationManager是spring事务管理的最基本接口.
如hibernate 事务HibernateTrasactionManager
   JDBC事务 DataSourceTrasactionManager
   Jta事务TrasactionManager
   WebLogic事务WebLogicJtaTrasactionManager
   Jdo事务 JdoTrasactionManager
  Jms事务 JmsTrasactionManager
这些事务管理都实现上面platformTracsationManager的接口
在从事务相关开发不能不说到事务的几个属性:
事务的传播特性,事特的隔离级别, 是否是只读,事务的超时等
事务的传播特性:
Propagation_required --必需在一个事务中执行:如果方法在被一个事务调用就加入该事务中否则启动一个新的事务.
Propagation_suport   --如果方法在被一个事务调用则加入到该事务中去,否则就不事务中执行.
Propagation_required_new --不管怎么样该当都必需在一个新的事务中执行
Propagation_not_suport --不在事务中执行:如果方法被一个事务调用则该事会被挂起 执行当方法后再回到事务方法中去.
Propagation_never --永远不在一个事务中执行否则抛出异常.
Propagation_Mandatory --必需在一个事务中运行如果不在则抛出异常.
Propagation_Nested  - 如果被一个事务调用则嵌入事务内起一个新事务执行,否则单独一个新事务中执行.在嵌入式事务内事务的回滚不会影响外部的事务,外部的事务会影响内部事务 .这个事务只对jdbc 事务起效.
事务的隔离级别有:
Read uncommit [ISOLATION_READ_UNCOMMIT]
读未提交的数据:会出现脏读,不可重复读,幻读
Read commit[ISOLATION_READ_COMMIT]
读取提交的数据:会出现不可重复读,幻读
Tepeatable read[ISOLATION_TEPEATABLE_READ]
可重复读:会出现不可重复读
Serializable[ISOLATION_SERIALIZABLE]
串行化
脏读:什么是脏读,会读取别人没有提交的更新数据.
例子:
1.Mary的原工资为1000, 财务人员将Mary的工资改为了8000(但未提交事务)
2.Mary读取自己的工资 ,发现自己的工资变为了8000,欢天喜地!
3.而财务发现操作有误,回滚了事务,Mary的工资又变为了1000
像这样,Mary记取的工资数8000是一个脏数据。
<span style="background-color: rgb(240, 240, 240); font-family: Arial, Helvetica, sans-serif;">不可重复读:在一个事务中多次读取同一条记录但是读取不同的结果:</span>
 例子:
1.在事务1中,Mary 读取了自己的工资为1000,操作并没有完成
  2.在事务2中,这时财务人员修改了Mary的工资为2000,并提交了事务.
  3.在事务1中,Mary 再次读取自己的工资时,工资变为了2000
解决办法:如果只有在修改事务完全提交之后才可以读取数据,则可以避免该问题。
幻读:读取到另一个已提交的insert语句
 例子:
 目前工资为1000的员工有10人。
1.事务1,读取所有工资为1000的员工。
2.这时事务2向employee表插入了一条员工记录,工资也为1000
 3.事务1再次读取所有工资为1000的员工 共读取到了11条记录, 
解决办法:如果在操作事务完成数据处理之前,任何其他事务都不可以添加新数据,则可避免该问题
一般人都很容易知到脏读会产生问题那么幻读书和不可重复读会出现什么问题呢?这个问题我在网上找一个文章在最后补上.
 
是否只读:
只读会提高数据库的访问性能.如在hibernate操作时就可以避免不必要的flush操作.
超时机制:
很多应该都有一个超时的机制类似socket的操作等因为如果我做一个操作如果无限期的等待不光会占资源我们的业务也可能不能等这么久.再说长期占用一个资会到资源用光如数据库的有限的的连接数会很快被占光.
spring默认发生runtime Exception是不会回滚事务的.但我可以通配置exception来使它回滚
spring事务有两种方式:编程式事务和声明式事务
Spring的声明式事务:
通常是指在配置文件中对事务进行配置声明,其中包括了很多声明属性,具体可以参考《Spring高级编程》这本书,它是通过Spring Proxy帮你做代理,自己不用额外的写代码,只要在Spring配置文件中声明即可;
编程式事务:
就是指通过硬编码的方式做事务处理,这种处理方式需要写代码,事务中的逻辑可以自己定制.
Spring官方建议声明式的使用.这个也是我常用的因为方便嘛:)
补充脏读幻读不可重读的理解转来自网上的一文章:
事务场景</strong>是这样的:
对于同一个银行帐户A内有200元,甲进行提款操作100元,乙进行转帐操作100元到B帐户。如果事务没有进行隔离可能会并发如下问题:
1、第一类丢失更新:首先甲提款时帐户内有200元,同时乙转帐也是200元,然后甲乙同时操作,甲操作成功取走100元,乙操作失败回滚,帐户内最终为200元,这样甲的操作被覆盖掉了,银行损失100元。
2、脏读:甲取款100元未提交,乙进行转帐查到帐户内剩有100元,这是甲放弃操作回滚,乙正常操作提交,帐户内最终为0元,乙读取了甲的脏数据,客户损失100元。
3、虚读:和脏读类似,是针对于插入操作过程中的读取问题,如丙存款100元未提交,这时银行做报表进行统计查询帐户为200元,然后丙提交了,这时银行再统计发现帐户为300元了,无法判断到底以哪个为准?
 大家好像觉得统计这个东西肯定是时时更新的,这种情况很正常;但是如果统计是在一个事务中的时候就不正常了,比如我们的一个统计应用需要将统计结果分别输出到电脑屏幕和远程网络某台计算机的磁盘文件中,为了
 提高性能和用户响应我们分成2个线程,这时先完成的和后完成的统计数据就可能不一致,我们就不知道以哪个为准了。
4、不可重复读:甲乙同时开始都查到帐户内为200元,甲先开始取款100元提交,这时乙在准备最后更新的时候又进行了一次查询,发现结果是100元,这时乙就会很困惑,不知道该将帐户改为100还是0。
和脏读的区别是,脏读是读取前一事务未提交的脏数据,不可重复读是重新读取了前一事务已提交的数据。
5、第二类丢失更新:是不可重复读的一种特例,如上,乙不做第二次查询而是直接操作完成,帐户内最终为100元,甲的操作被覆盖掉了,银行损失100元。感觉和第一类丢失更新类似。

在多个事务并发做数据库操作的时候,如果没有有效的避免机制,就会出现种种问题。大体上有三种问题,归结如下:
1、丢失更新
如果两个事务都要更新数据库一个字段X,x=100
事务A             事务B
读取X=100     
                  读取X=100
写入x=X+100
                  写入x=X+200
事务结束x=200
                  事务结束x=300
最后x==300
这种情况事务A的更新就被覆盖掉了、丢失了。
丢失更新说明事务进行数据库写操作的时候可能会出现的问题。
2、不可重复读
一个事务在自己没有更新数据库数据的情况,同一个查询操作执行两次或多次的结果应该是一致的;如果不一致,就说明为不可重复读。
还是用上面的例子
事务A             事务B
读取X=100     
                  读取X=100
读取X=100     
                  写入x=X+100
读取X=200     
事务结束x=200
                  事务结束x=200
这种情况事务A多次读取x的结果出现了不一致,即为不可重复读。
再有一情况就是幻影
事务A读的时候读出了15条记录,事务B在事务A执行的过程中删除(增加)了1条,事务A再读的时候就变成了14(16)条,这种情况就叫做幻影读。
不可重复读说明了做数据库读操作的时候可能会出现的问题。
3、脏读(未提交读)
防止一个事务读到另一个事务还没有提交的记录。
如:
事务A             事务B
                  读取X=100
                  写入x=X+100
读取X=200     
                  事务回滚x=100
读取X=100     
事务结束x=100
x锁 排他锁 被加锁的对象只能被持有锁的事务读取和修改,其他事务无法在该对象上加其他锁,也不能读取和修改该对象
s锁 共享锁 被加锁的对象可以被持锁事务读取,但是不能被修改,其他事务也可以在上面再加s锁。
封锁协议:
一级封锁协议:
在事务修改数据的时候加x锁,直到事务结束(提交或者回滚)释放x锁。一级封锁协议可以有效的防止丢失更新,但是不能防止脏读不可重复读的出现。
二级封锁协议:
在一级封锁的基础上事务读数据的时候加s锁,读取之后释放。二级封锁协议可以防止丢失更新,脏读。不能防止不可重复读。
三级封锁协议:
在一级封锁的基础上事务读数据的时候加s锁,直到事务结束释放。二级封锁协议可以防止丢失更新,脏读,不可重复读。
 
 
 
 
 
 
 
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值