Spring的声明式事务

 

<!-- [if !mso]> <style> v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} </style> <![endif]--><!-- [if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:PunctuationKerning/> <w:DrawingGridVerticalSpacing>7.8 &#30917;</w:DrawingGridVerticalSpacing> <w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery> <w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:Compatibility> <w:SpaceForUL/> <w:BalanceSingleByteDoubleByteWidth/> <w:DoNotLeaveBackslashAlone/> <w:ULTrailSpace/> <w:DoNotExpandShiftReturn/> <w:AdjustLineHeightInTable/> <w:BreakWrappedTables/> <w:SnapToGridInCell/> <w:WrapTextWithPunct/> <w:UseAsianBreakRules/> <w:DontGrowAutofit/> <w:UseFELayout/> </w:Compatibility> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!-- [if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" LatentStyleCount="156"> </w:LatentStyles> </xml><![endif]-->

 

<!-- [if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable {mso-style-name:&#26222;&#36890;&#34920;&#26684;; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} table.MsoTableGrid {mso-style-name:&#32593;&#26684;&#22411;; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; border:solid windowtext 1.0pt; mso-border-alt:solid windowtext .5pt; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-border-insideh:.5pt solid windowtext; mso-border-insidev:.5pt solid windowtext; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.0pt; font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} </style> <![endif]--><!-- [if gte mso 9]><xml> <o:shapedefaults v:ext="edit" spidmax="1029"/> </xml><![endif]--><!-- [if gte mso 9]><xml> <o:shapelayout v:ext="edit"> <o:idmap v:ext="edit" data="1"/> <o:rules v:ext="edit"> <o:r id="V:Rule1" type="callout" idref="#_x0000_s1026"/> <o:r id="V:Rule2" type="callout" idref="#_x0000_s1027"/> </o:rules> </o:shapelayout></xml><![endif]-->

Spring 的声明式事务

Spring 的声明式事务是通过 SpringAOPA 实现的,通过事务的声明信息, Spring 负责将将事务管理增强逻辑动态织入到业务方法相应连接点中。

其配置如下:

<? xml version = "1.0" encoding = "UTF-8" ?>

 

< beans xmlns = "http://www.springframework.org/schema/beans"

        xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"

         xmlns:aop = "http://www.springframework.org/schema/aop"

        xmlns:tx = " http://www.springframework.org/schema/tx "

xsi:schemaLocation = "

http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd

http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd " >

 

<!-- 数据源的配置 -->

< bean id = "dataSource" class = "org.apache.commons.dbcp.BasicDataSource" >

     < property name = "driverClassName" value = "oracle.jdbc.driver.OracleDriver" />

     < property name = "url" value = "jdbc:oracle:thin:@192.168.1.79:1521:avs" />

     < property name = "username" value = "user400" />

     < property name = "password" value = "user400" />

</ bean >

<!-- 事务管理器 -->

< bean id = "transactionManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager" >

       < property name = "dataSource" ref = "dataSource" />

</ bean >

 

<!— 事务增强 -->

< tx:advice id = "txAdvice" transaction-manager = "transactionManager" >

    < tx:attributes >   // 事务属性定义

       < tx:method name = "update*" propagation = "REQUIRED" />

       < tx:method name = "*" read-only = "true" />

    </ tx:attributes >

</ tx:advice >

 

<!— 事务增强的切面 -->

< aop:config >

    < aop:pointcut id = "allMethod" expression = "execution(* com.Xxx.Xxxx.service.*Xxx.*(..))" />

<!-- [if gte vml 1]><v:shapetype id="_x0000_t104" coordsize="21600,21600" o:spt="104" adj="12960,19440,7200" path="ar0@22@3@21,,0@4@21@14@22@1@21@7@21@12@2l@13@2@8,0@11@2wa0@22@3@21@10@2@16@24@14@22@1@21@16@24@14,xewr@14@22@1@21@7@21@16@24nfe"> <v:stroke joinstyle="miter"/> <v:formulas> <v:f eqn="val #0"/> <v:f eqn="val #1"/> <v:f eqn="val #2"/> <v:f eqn="sum #0 width #1"/> <v:f eqn="prod @3 1 2"/> <v:f eqn="sum #1 #1 width"/> <v:f eqn="sum @5 #1 #0"/> <v:f eqn="prod @6 1 2"/> <v:f eqn="mid width #0"/> <v:f eqn="ellipse #2 height @4"/> <v:f eqn="sum @4 @9 0"/> <v:f eqn="sum @10 #1 width"/> <v:f eqn="sum @7 @9 0"/> <v:f eqn="sum @11 width #0"/> <v:f eqn="sum @5 0 #0"/> <v:f eqn="prod @14 1 2"/> <v:f eqn="mid @4 @7"/> <v:f eqn="sum #0 #1 width"/> <v:f eqn="prod @17 1 2"/> <v:f eqn="sum @16 0 @18"/> <v:f eqn="val width"/> <v:f eqn="val height"/> <v:f eqn="sum 0 0 height"/> <v:f eqn="sum @16 0 @4"/> <v:f eqn="ellipse @23 @4 height"/> <v:f eqn="sum @8 128 0"/> <v:f eqn="prod @5 1 2"/> <v:f eqn="sum @5 0 128"/> <v:f eqn="sum #0 @16 @11"/> <v:f eqn="sum width 0 #0"/> <v:f eqn="prod @29 1 2"/> <v:f eqn="prod height height 1"/> <v:f eqn="prod #2 #2 1"/> <v:f eqn="sum @31 0 @32"/> <v:f eqn="sqrt @33"/> <v:f eqn="sum @34 height 0"/> <v:f eqn="prod width height @35"/> <v:f eqn="sum @36 64 0"/> <v:f eqn="prod #0 1 2"/> <v:f eqn="ellipse @30 @38 height"/> <v:f eqn="sum @39 0 64"/> <v:f eqn="prod @4 1 2"/> <v:f eqn="sum #1 0 @41"/> <v:f eqn="prod height 4390 32768"/> <v:f eqn="prod height 28378 32768"/> </v:formulas> <v:path o:extrusionok="f" o:connecttype="custom" o:connectlocs="@8,0;@11,@2;@15,0;@16,@21;@13,@2" o:connectangles="270,270,270,90,0" textboxrect="@41,@43,@42,@44"/> <v:handles> <v:h position="#0,topLeft" xrange="@37,@27"/> <v:h position="#1,topLeft" xrange="@25,@20"/> <v:h position="bottomRight,#2" yrange="0,@40"/> </v:handles> <o:complex v:ext="view"/> </v:shapetype><v:shape id="_x0000_s1028" type="#_x0000_t104" style="position:absolute; left:0;text-align:left;margin-left:251.1pt;margin-top:8.7pt;width:46.9pt; height:45.05pt;rotation:-4983681fd;z-index:3" mce_style="position:absolute; left:0;text-align:left;margin-left:251.1pt;margin-top:8.7pt;width:46.9pt; height:45.05pt;rotation:-4983681fd;z-index:3" adj="13088,17408,10861"/><![endif]--><!-- [if !vml]--><!-- [endif]--><!-- [if gte vml 1]><v:shape id="_x0000_s1026" type="#_x0000_t63" style="position:absolute;left:0;text-align:left; margin-left:315pt;margin-top:15.6pt;width:108pt;height:46.8pt;text-indent:0; z-index:1" mce_style="position:absolute;left:0;text-align:left; margin-left:315pt;margin-top:15.6pt;width:108pt;height:46.8pt;text-indent:0; z-index:1" adj="-900,-9415"> <v:textbox> <![if !mso]> <table cellpadding=0 cellspacing=0 width="100%"> <tr> <td><![endif]> <div> <p class=MsoNormal><span style="font-family:&#23435;&#20307;;mso-ascii-font-family:"Times New Roman"; mso-hansi-font-family:"Times New Roman";color:red" mce_style="font-family:&#23435;&#20307;;mso-ascii-font-family:"Times New Roman"; mso-hansi-font-family:"Times New Roman";color:red">&#23450;&#20041;&#30446;&#26631;&#26041;&#27861;</span><span lang=EN-US style='color:red'><o:p></o:p></span></p> </div> <![if !mso]></td> </tr> </table> <![endif]></v:textbox> </v:shape><![endif]--><!-- [if !vml]--> <!-- [endif]-->    < aop:advisor advice-ref = "txAdvice" pointcut-ref = "allMethod" />

</ aop:config >              引用事务增强

 

</beans>

 

首先我们要引入 tx 命名空间,如 <beans> 中红色标记的

 

aop 命名空间中,通过切点表达式,将 com.auv.auvtech400.service 包下所有以 Xxx 结尾的类纳入了事务增强的范围。

 

注意: 使用 aop/tx 配置事务管理时,因为需要用到 AspectJ 的切点表达式解析功能,所以需要将 Spring/lib/aspectjweaver.jar 引入到类路径中

 

    <aop:advisor> 引用的 txAdvice 增强是在 tx 命名空间上定义的,首先,事务增强需要一个事务管理器的支持, <tx:advice> 通过 trasaction-manager 属性引用事务管理器,它默认查找名为 transactionManager 的事务管理器,所以如果事务管理器命名为 transactionManager ,可以不指定 transaction-manager 属性。

 

tx:method 拥有以下的属性

name : 与事务属性关联的方法,可使用通配符( *

propagation : 事务的传播行为,默认值为 REQUIRED ,可选的值有:

         REQUIRED: 如果当前没有事务就创建一个,如果存在一个事务,加入到这个事务中

         SUPPORTS :支持当前事务,如果当前没有事务,就以非事务执行

         MANDATORY :使用当前事务,没有事务抛异常

         REQUIRES_NEW :新建事务,如果当前存在事务,把当前事务挂起

         NOT_SUPPORTED :以非事务执行,如果当前存在事务,就把当前事务挂起

        NEBER :以非事务方式执行,如果当前存在事务则抛出异常

        NESTED :如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行和 REQUIRED 类似的操作

isolation : 事务隔离级别,默认值为 DEFAULT ,可选的值:

        DEFAULTREAD_NUCOMMITEDREAD_COMMITEDREPEATABLE_READSERIALIZABLE

DEFAULT :表示数据库默认的级别, 对大部分数据库而言,通常这值就是

TransactionDefinition.ISOLATION_READ_COMMITTED

 

其他隔离级别具体意义如下表:

隔离级别

脏读

不可

重复读

幻想读

第一类

丢失更新

第二类

丢失更新

READ_NUCOMMITED

允许

允许

允许

READ_COMMITED

允许

允许

REPEATABLE_READ

允许

SERIALIZABLE

 

SERIALIZABLE :最严格的级别,事务串行执行,资源消耗最大

REPEATABLE_READ : 保证了一个事务不会修改已经由另一个事务读取但未提

(回滚)的数据。避免了 脏读取 不可重复读取 的情况,但是带来了更多的性能损失。

READ_COMMITED : 大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了 脏读取 。该级别适用于大多数系统。

READ_NUCOMMITED : 保证了读取过程中不会读取到非法数据。隔离级别在于处理多事务的并发问题。

事务的隔离级别和数据库的并发性是对立的,两者此增彼长。一般来说,使用

READ_NUCOMMITED 隔离级别的数据库拥有最高的并发性和吞吐量,而使用

SERIALIZABLE 隔离级别的数据库并发性最低。

 

 

<!-- [if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:PunctuationKerning/> <w:DrawingGridVerticalSpacing>7.8 &#30917;</w:DrawingGridVerticalSpacing> <w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery> <w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:Compatibility> <w:SpaceForUL/> <w:BalanceSingleByteDoubleByteWidth/> <w:DoNotLeaveBackslashAlone/> <w:ULTrailSpace/> <w:DoNotExpandShiftReturn/> <w:AdjustLineHeightInTable/> <w:BreakWrappedTables/> <w:SnapToGridInCell/> <w:WrapTextWithPunct/> <w:UseAsianBreakRules/> <w:DontGrowAutofit/> <w:UseFELayout/> </w:Compatibility> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!-- [if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" LatentStyleCount="156"> </w:LatentStyles> </xml><![endif]-->

 

<!-- [if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable {mso-style-name:&#26222;&#36890;&#34920;&#26684;; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} </style> <![endif]-->

数据并发问题:

1. Dirty read-- 读脏数据。也就是说,比如事务 A 的未提交(还依然缓存)的数

据被事务 B 读走,如果事务 A 失败回滚,会导致事务 B 所读取的的数据是错误的。

2. nurepeatable read-- 数据不可重复读。事务 A 读取了事务 B 已经提交的更改数据。比如事务 A 中两处读取数据 -total- 的值。在第一读的时候, total100 ,然后事务 B 就把 total 的数据改成 200 ,事务 A 再读一次,结果就发现, total 竟然就变成 200 了,造成事务 A 数据混乱。

3. phantom read-- 幻象读数据。 A 事务读取 B 事务提交的新增数据。它和 nurepeatable read 相似,但是 unreaptable read 是读取了已经提交的更改数据,而 phantom read 是读取了已经提交的新增数据。为了防止读取到更改的数据,只需要对操作的数据添加行级锁,阻止操作中的数据放生变化,而防止读取到新增的数据,则往往需要添加表级锁 ---- 将整个表锁住,防止新增数据。

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

5. 第二类丢失更新: A 事务覆盖 B 事务已经提交的数据。

 

tmeout : 事务超时的时间,默认值为 -1

read-only : 事务是否只读,默认值为 false

rollback-for: 触发事务回滚的Exception,默认值是所有运行期异常回滚,可以配置多个以逗号

no-rollback-for: 不触发事务回滚的Exception,默认值是所以检查型异常不回 滚,可以配置多个,以逗号隔开,

                         以上属性只有name是必须的,其他为可选

<!-- [if gte mso 9]--> 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值