我的日常

登录/注册
您现在的位置:论坛 盖世程序员(我猜到了开头 却没有猜到结局) 盖世程序员 > struts2+hibernate+spring如何配置事务
总共48086条微博

动态微博

查看: 1524|回复: 2

struts2+hibernate+spring如何配置事务

[复制链接]
admin    

1244

主题

544

听众

1万

金钱

管理员

  • TA的每日心情

    2021-2-2 11:21
  • 签到天数: 36 天

    [LV.5]常住居民I

    管理员

    跳转到指定楼层
    楼主
    发表于 2014-09-03 21:20:33 |只看该作者 |倒序浏览
    struts+hibernate+spring整合开发web应用是相当流行的,只需要简单的配置就能轻松的对数据库进行crud操作,下面就hibernate+spring的配置做一下剖析,一边与大家一起分享经验: % e' B. y& {$ w* O7 [

    0 J$ E4 M. G4 U, e( v" m1 J& {" w1、  准备工作:
    + H# t3 G0 M( I$ W4 p
    8 Y! S  Z3 g7 |6 C* I可以利用hibernate tools生成相关映射文件已经po对象、dao对象,dao也可以自己手动编写,无非就是实现crud,如果通过继承hibernate提供的HibernateDaoSupport,则可以更轻松的实现 1 A- @- v5 T: f7 I& U7 L
    * w6 t" |$ s$ {  [0 z4 `5 N
    关键就在于配置文件,下面看一个样例app.xml:
    ( r& j- Q( w6 x) _( d! P) d. Q9 s2 w
    <?xml version="1.0" encoding="utf-8"?>
    . w6 P8 u4 V1 M  T7 g: j9 h% C9 [# e; R  b
    <beans xmlns="http://www.springframework.org/schema/beans"
    ( d0 H1 m0 |. `! e9 D  e/ ~8 ?  [8 A' }" X; b3 m
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1 o( |% @2 V5 k* |& i0 n' R0 ~
    # a$ @3 Z3 L4 J9 S       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    + n7 f5 f! [6 X6 q3 t6 w
    # U& _2 k" Y' F  y<!--配置数据源-->
    1 P; p: |+ H+ v3 _- p
    6 c6 v& S: K" c; T6 ?( X<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> & n2 ?. P* I2 ?. P& B! ~9 }0 n
    . A/ ?0 {7 [7 o; J
           <!-- 指定连接数据库的驱动 -->
    , V  q# R3 K/ ?5 d( Q! b
    0 ^' H1 m: y, E       <property name="driverClass" value="com.mysql.jdbc.Driver"/> ) z" S7 R" _! H4 Q' r9 }
    & c$ V" e4 W6 A  h
           <!-- 指定连接数据库的URL --> 3 Q2 h9 \7 f& }9 |; K
    ' E0 Z1 S: w1 q- ]5 L, Z1 C
           <property name="jdbcUrl" value="jdbc:mysql://localhost/auction"/> / `9 v! J% W# |3 m1 P

    3 r( z4 K3 J$ Z" O8 ^4 y' r# }4 z       <!-- 指定连接数据库的用户名 --> 3 S6 J5 {7 m, |/ s9 S  c# N

    1 e. C. Q6 q# L0 J6 m! J2 Z       <property name="user" value="root"/>
    ) ?6 w$ N9 Y7 W+ v% K0 F7 Y% z
    8 B: x' H- l& |+ y! k       <!-- 指定连接数据库的密码 --> $ e6 K* y$ Z+ p# T9 }6 H  K

    7 v- K2 q( w% r  Y       <property name="password" value="root"/>
    7 a8 }4 S. e) O  x' A$ e/ e6 K( ]9 d0 {2 u5 e' p
           <!-- 指定连接数据库连接池的最大连接数 --> 4 T4 e' B- g$ Z  `# M

    # z$ H, x6 b/ l* B! w       <property name="maxPoolSize" value="20"/> $ B8 h! c$ p6 q4 n  P$ ]- q

    + \; U2 @/ e% M1 j" `. d       <!-- 指定连接数据库连接池的最小连接数 --> $ w5 I. A8 ?6 Y  m
    & j7 r( i( G5 P/ P. O# u
           <property name="minPoolSize" value="1"/>
    ; w7 q# e' m2 }) R% Z, D
    ( o4 w5 W3 F' S$ Y* B- o; i       <!-- 指定连接数据库连接池的初始化连接数 --> 6 ^2 F6 m9 s; D' I4 {* U
    8 L% w$ v7 D$ ^+ @: b/ q8 @
           <property name="initialPoolSize" value="1"/> ! o9 h: k9 v" i. ]6 U
    8 ^& V; V$ R4 p! s# r; ?  K; |6 q) W
           <!-- 指定连接数据库连接池的连接的最大空闲时间 -->
    4 h2 \* w1 n$ A
    & a( k7 Y7 i; h+ g5 Z) I+ K& A       <property name="maxIdleTime" value="20"/>
    & v2 _* t; {" Y9 _+ f
    1 _: L& Y; X, N; b3 R    </bean> 2 O( }1 k  g0 W! r$ t4 n) b& {
    3 L: x) i. }3 b) k) s4 i
       ! B) c5 c& ~$ H3 e9 A- T

    ( ]  [% `6 k! A8 B4 l. g* A( P    <!--配置数据库会话工厂--> ) c' s; J9 B  z0 b3 j+ T1 W2 v
    - T0 y! e' k5 h, D
        <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 6 E0 l  Z4 H) h; u9 e

    3 o+ w% K$ ?: R       <property name="dataSource" ref="dataSource"/>
    , x" E5 a- w2 K, ?! Y5 @. B+ U) t! P, |$ x( B6 Q5 h$ L2 _3 o
           <property name="mappingResources">
    7 K" z! t* Z# T) h
    8 ?3 P9 s: R4 v7 p& K+ e% A* o           <list> . P& l" ~, M) x9 m) l7 O4 m
    ) m( ~* V# ]4 L8 m
                  <value>com/ouya/User.hbm.xml</value>   @; T) u4 j2 S

    * H- C: ?4 _6 i5 f9 N           </list> 1 B7 S: z8 j5 B
    8 b) b5 \7 ]0 b+ Q7 F
           </property>
    / K. @" _5 ?) x2 l- o+ Y. p: H; `# L$ U/ F, `3 h  k: R5 b
            <property name="hibernateProperties"> : `6 ?4 x, g9 `0 _) a: }) ~
    , [: ?* ?0 X' o5 @+ c! q8 D' k' m
        <props> 0 ^  O: p) F! `, _
    3 A+ K& P# F: T) k+ x4 F- D: A9 j
         <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
    ' g9 g. R1 s* }1 A6 s3 g4 P8 O" |& l# H- P9 I. X4 M
         <prop key="hibernate.show_sql">true</prop> 7 v( J' c1 c/ E* W
    , K6 P1 J" D2 ]$ d
         <prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
    , A# m; `( C7 e( ]* T/ ]
    0 X1 X! V5 ~) u7 g    </props>   W# Q9 y0 v' ^, @6 T" B2 q3 M
    1 q8 S1 t$ ?! k. B
       </property>
    5 q% ^1 Y  a' i0 X* M% ^3 A9 ?/ e: z5 w2 f
        </bean>
    6 h* {; ~/ D3 {/ ~( d  f$ G- A; ^+ m# X7 a7 G0 A

    6 g4 c' T/ q& x* v7 c
    + Z* c% }, y# L( E8 ~' ?<!--配置事务管理器-->
    , r3 t. w7 U  z' C9 o
    4 \3 t# e% v: b& C; M  D: g8 y<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 1 Y/ l) Z- Q6 \% |1 f. `
    ) e" d  J9 H8 b1 G  {; o+ W
       <property name="sessionFactory"><ref local="sessionFactory"/></property> : I, z! r* y/ N5 |

    9 |5 [% X/ v) C  w& y! ]2 o1 Q2 q</bean>
      \  s* r  F) u: G3 O$ p5 l! _2 P% [& ]6 l. m( w9 F9 {# K
        <!—-配置Spring 事务管理器代理 --> % M' c+ _( @/ `+ ~* g6 ~) ?. q

    8 U6 ^, E7 |9 m% |- L<bean id="transactionProxyFactory" abstract="true" lazy-init="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 7 T: n1 i: V! E2 f( y9 u6 z1 l) j
    * c( M$ w  A# z8 _8 {+ J! b
        <property name="transactionManager">
    1 s8 M  @" ?8 W6 m) j. X' C6 U2 y1 ?0 L, H" m9 q9 ?
             <ref local="transactionManager"/>
    $ B3 O5 f% U' g' M
    + \$ k$ Q! K( w  P/ K# S& X) h    </property>
    . D# m( t  Y6 G. B' t
    $ A9 f( z3 z! B) L  D2 e! N* q" [    <property name="transactionAttributes">
    8 d& S; \. n. w9 B- @0 z
    0 M1 X- U  X7 Z/ S1 V         <props> - f$ t; s* n2 O' ?9 R' g

    / c$ J# l! [" f' Z; K+ |7 G1 W2 J          <prop key="save*">PROPAGATION_REQUIRED</prop> . R; F" R8 a: c$ h
    4 ~% i  W1 f# l* H; w
               <prop key="insert*">PROPAGATION_REQUIRED</prop> & N6 ~$ L0 a1 E! b; w6 s

    ' E) r6 Q# ^* t7 q9 l$ f! z6 x4 \0 T           <prop key="del*">PROPAGATION_REQUIRED</prop> . p: ~* U+ P1 }6 x& \/ G# c. H

    % R( c: Q* \+ N# a: h2 q: H6 q           <prop key="add*">PROPAGATION_REQUIRED</prop> 6 k# X! V2 c# C. |' _" Q
    1 K! I4 h) r/ b8 t
               <prop key="update*">PROPAGATION_REQUIRED</prop>
    6 R3 b6 j( ~! V* a
    7 Q6 \2 J3 Y" G5 \           <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
    / r4 a% f- i, v. O* w3 T4 m! p) b" o& R4 {9 e" {" ^5 _' M& J; n
               <prop key="search*">PROPAGATION_REQUIRED,readOnly</prop> * E  b' b$ w/ K. Q3 m& t5 f
    # g0 o  t$ w% c
               <prop key="remove*">PROPAGATION_REQUIRED,readOnly</prop> : D, m2 Z5 ^8 f3 v3 Z7 k! T2 I
    . `6 Q+ H; ?- ~+ R- j' K; t
               <prop key="query*">PROPAGATION_REQUIRED,readOnly</prop>
    ! l: S7 A3 O! b0 p' s" Y1 f7 J% L% i
               <prop key="list*">PROPAGATION_REQUIRED,readOnly</prop> % ^$ m2 P2 d. z' j1 b7 d* x

    & g8 M: e5 [  G7 ]2 L4 m           <prop key="count*">PROPAGATION_REQUIRED,readOnly</prop> ' C7 L( ]0 `7 I" X- G3 {  J

    ' K# c- \: q8 l$ h% L) V           <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
    1 @/ X6 w7 L6 D7 q% T* Q0 R: X4 ^9 m: `( {( d8 V+ D6 C2 p
        </props> : e* r5 x# I1 @

    - C( G( @9 {# ^, B6 r6 e8 z9 z   </property>
    7 I7 g  B6 v# D; ~% D" p$ z9 E! G' @' z# @7 Q4 x
        </bean>
    " j" g4 a. ~) b' \0 k# t! a0 ~
    1 c( P2 M" @" P% {    <!-- Hibernate模板 -->
    , i. [; J4 x9 E6 k% H6 A+ C( ]
    : y4 }7 J' l0 i9 q7 K& |$ d3 n<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"> / W$ `7 L( E. L4 x3 H0 ]

    * n( k7 g1 K& X% ~" A7 n" e   <property name="sessionFactory">
    - z# @5 W8 f4 Z6 I7 e% E  [+ k9 {5 n$ c! E: Q1 j7 A( r1 g; E
        <ref local="sessionFactory" /> & ^% F$ a% ]( H& r. j( V
    0 q5 z' C  ?$ W! A6 N
       </property>
    3 l6 T# _- \' H8 |  I
    " G& m1 I3 B! U# Z& Q) [</bean>
    % \( B% J1 z, z4 q! f, m
    . V% Z' a0 ^2 f    <!--服务层对象--> " O7 A+ U3 Z; ?5 L
    . P+ y' o5 E* ?  V. ^; r1 k: v" h9 }
        <bean id="us" class="com.ouya.UserService">
    0 k4 G( @! U. s8 M
    ! e; P* ]: S! C. S) \     <property name="userDao">
    0 ?5 u. u9 K3 }, ~% d1 K* v1 c& w) v; \" p7 P. i# o3 |2 ?
          <ref local="userDao"/>
    ) t/ S5 ?5 Y( w- d6 q
    ' a2 }6 c9 I6 K7 P     </property> " V. [/ n. u" v4 f% s
    ( J. T5 Y+ c. j- s/ Y
        </bean>
    2 M- o: w: e4 b$ d. w7 ~, c6 q0 \" c$ t) L
        <!-- spring代理用户服务对象 --> ) n% p8 T7 h; [  s

    * C1 M$ Z. s" k# Q6 L<bean id="userService" parent="transactionProxyFactory"> ( E, @3 n( t1 C0 p  {; x1 u) b

    $ e3 l( y3 y/ m% P* s' {( G<!-- 如果上面的服务层对象实现了接口,则此处必须设置proxyTargetClass为true,否则会报classcast异常 -->
    : S! B' u/ G9 N; @6 x9 ]) s1 c) ~% L
    <!--<property name="proxyTargetClass" value="true"/>--> ! n1 o, Y/ D( u  p; n
    1 s8 n; ]' F9 F
           <property name="target" ref="us"/> ) r- t" K  I; `* s6 p9 L
    . _; |1 ?4 t. D* O9 Z
    </bean>
    7 P7 a9 R1 e; `% y5 N* r, w: g- B6 a. \+ v  p/ f2 A7 S3 g
        <!-- 用户数据访问对象DATA ACCESS OBJECT --> 9 N# X2 a) N. C1 Q! L
    - m( x+ u6 w$ p4 s. Q6 h
    <bean id="userDao" class="com.ouya.UserDAO"> & d$ B& e  e( Z# Q9 n. I

    0 {! `# p" R5 ^* G   <property name="hibernateTemplate" ref="hibernateTemplate"/> 2 d7 b0 `5 W2 u$ _' q
    ) H2 y9 A; T* {" D/ r1 b0 K6 m
    </bean>
    $ r: E1 K( [) C% R$ l& d0 I4 b! w% ^1 F! W7 z
        </beans>
    + U9 O5 S' r* k7 L& g4 |6 @9 F3 V* @1 I; g8 E! |" C% ^
    可以看到配置文件的步骤:
    ) G4 J; m8 X3 q" f  \8 l9 _: {# l) h) }' U/ u9 Z0 L9 G
    1、  配置数据源 6 b! ~1 [+ j  j0 K1 @4 t

    3 L; b& f4 }& r& K, g2、  配置会话工厂(依赖注入上面的数据源,还要注入hbm映射文件[注意正确的位置]、hibernate属性文件) , ^# [6 I  f6 W' W% w( p
    , A7 e+ `  K2 u3 R) I: H; l, L
    3、  配置事务管理器(依赖注入上面的会话工厂)   V1 _1 }. ~; V- ^- y. d( O- J
    % I) M- A5 n2 L, w( c4 f4 N! }9 r0 R! o
    4、  Spring中声明事务管理器(根据需要又可分为几种,但都要依赖注入上面的事务管理器,此外还需要配置transationAttributes)
    0 E, {4 P9 @' p: K* E) }8 ~* D* @& c2 t7 p8 h1 b0 b* G: x+ n
    后面的一些普通的bean配置就不用说了
    5 T0 l! _% @0 Z0 v6 Q  ^+ L. W  k, A- ]
    上面的例子中使用的声明事务管理器是:TransactionProxyFactoryBean,这样的话我们就需要在后面配置目标bean,比如上面的例子中我们的原服务对象是id为us的UserService(没有实现接口),所以我们为他配置了id为userService的代理对象(目标bean),程序中使用时只能通过使用代理对象才能实现数据库操作功能(代理对象的父类是上面声明的事务管理器,一边我们使用的时候开启事务),如果直接使用服务对象就无法开启事务
    3 S1 N( j% M' i3 {$ M" x1 _: F/ G" b/ Z8 `' P. h
    程序中调用:UserService us = (UserService) app.getBean("userService"); " t/ t( _6 ?8 x) ?9 Q
    ! o% o6 B. C/ m4 q& Z$ [
    注:userService就是上面配置的代理对象的id,而不是原服务对象的id ( C& M2 i. N4 S+ S! L0 ~

    ! H$ \7 K0 |, j: b% m5 f' n# D6 \& @; @% i0 q! x9 a4 W5 }

    + ~; ~! H8 j' W" g% G' N  o但是如果我们想通过原服务对象的id来使用对象,则我们需要使用代理事务管理器BeanNameAutoProxyCreator(根据beanname自动代理),上面的配置文件需要做改动,做两件事(当然先要删除原来配置的TransactionProxyFactoryBean,不然就混乱了,可能会报错的): ! b% c% D1 J1 W7 U' }

    6 C  k3 I4 D2 O4 P' O7 f1、  增加一个事务拦截器
    1 d: s( o# z) e) l& B+ w2 t  ^7 b( |2 U$ J
    <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
    " e' [" j, a. }: D7 m( |8 P+ e9 X. l* L$ q/ E
        <property name="transactionManager">
    , a/ w$ P: U+ Q( M. F  P6 J( }1 {* Y  q) o8 ^( ~' V
             <ref local="transactionManager"/> - ]7 ?  w7 e. x% O; r: H
    $ w' t* }' r' k& j% ^
        </property>
    ( m7 j0 C# g% v3 @; l/ ^6 r4 L, ~2 U5 M1 r! _9 M& |
        <property name="transactionAttributes"> 3 H1 u$ T: U( f- g% p
    9 b$ P( U4 l- e9 B9 O
             <props> 1 T+ o: k1 T' H5 F6 K+ b
    % x4 Z: l$ q0 x1 X5 _! o
              <prop key="save*">PROPAGATION_REQUIRED</prop>
    ; ^2 e1 m$ a5 g; [' r' M. L
      R2 |1 h) U' d: P9 _           <prop key="insert*">PROPAGATION_REQUIRED</prop> . V+ i- H% H# t2 p' H: ^
    # D$ T" ]: t' l8 m
               <prop key="del*">PROPAGATION_REQUIRED</prop>
    ( M1 [& [0 |' b) X0 c- {8 J
    7 N7 T/ M( D" w5 g1 ]2 n1 y$ h8 }! D           <prop key="add*">PROPAGATION_REQUIRED</prop> * p. t9 w$ Z! t3 m
    : D8 T0 Z3 \% e0 u! D- W
               <prop key="update*">PROPAGATION_REQUIRED</prop>
    ) l* b, [- H+ _0 U( V* _$ s1 T
    & y4 L1 g+ U7 M& B: U3 ~           <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
    9 B% P* g1 f9 J" r6 e% D( N% f0 U2 j4 N8 Y+ \) Q
               <prop key="search*">PROPAGATION_REQUIRED,readOnly</prop>   Z% A7 J0 l8 T% i* a' S# j4 c

    1 k, u4 V6 {( g           <prop key="remove*">PROPAGATION_REQUIRED,readOnly</prop>
    . B5 I8 n1 p( M" S9 |; I2 ]" Z' o" g2 C( K$ y: G' o
               <prop key="query*">PROPAGATION_REQUIRED,readOnly</prop> # B8 y* r+ l$ t" p" ~3 f5 m3 x
    : l3 H3 F( O( p2 u
               <prop key="list*">PROPAGATION_REQUIRED,readOnly</prop> & C; K' Y& a+ W1 ?) U
    & u7 Q6 |2 z. y0 e  D: T2 s
               <prop key="count*">PROPAGATION_REQUIRED,readOnly</prop>
    . J+ e. X9 g, V7 @) ~& _7 w# b$ J, k0 |$ w
               <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
    - l- [# {% \& f
    7 e1 ?7 L. [# |9 u7 S& B    </props>
    ; k1 e& }( n  _$ Z
    0 B% {5 g; ^- x   </property>
    + v/ m( w7 ^0 c/ d* W1 q
    * x  ]% i+ F* \2 ^1 ]</bean> / ~; u$ X+ Q2 e- b: M0 Y/ i4 D$ q
    1 G  J' f' ]( {" l9 {! f

    # o) ~, J' g/ `1 Y$ b- H5 f
    * U$ T5 v  n6 y) w- V8 P

    科帮网 1、本主题所有言论和图片纯属会员个人意见,与本社区立场无关
    2、本站所有主题由该帖子作者发表,该帖子作者与科帮网享有帖子相关版权
    3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和科帮网的同意
    4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
    5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
    6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
    7、科帮网管理员和版主有权不事先通知发贴者而删除本文


    JAVA爱好者①群:JAVA爱好者① JAVA爱好者②群:JAVA爱好者② JAVA爱好者③ : JAVA爱好者③

    红红火火恍恍惚惚
    admin    

    1244

    主题

    544

    听众

    1万

    金钱

    管理员

  • TA的每日心情

    2021-2-2 11:21
  • 签到天数: 36 天

    [LV.5]常住居民I

    管理员

    沙发
    发表于 2014-09-03 21:20:54 |只看该作者
    2、  定义自动代理事务管理器 9 x+ n2 B. H7 e9 n# z* _( A
    1 N% S' ^; R) _8 g# H
    <!-- 定义BeanNameAutoProxyCreator-->
    4 x3 W$ ]( A5 |: j# H5 s% I& w; w' i  o% X; V
    <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> : N& d" q( \5 j7 X, w

    ( h: `+ Z! n+ Q6 |<!--  如果服务层对象是接口实现类,则需要设置proxyTargetClass属性为true --> 9 j3 g1 d7 |$ S2 L

    ' w2 [) ]7 a2 b1 |* h+ x<!--<property name="proxyTargetClass" value="true"-->
    . \8 v6 A4 j/ O* [  T; Q9 V* T0 O# A7 ]  Y9 U
            <!--  指定对满足哪些bean name的bean自动生成业务代理 -->
    ( O5 j4 C) E  p' G( K5 u- k# C# q0 \3 L. \9 b
            <property name="beanNames">
    2 V- @: o; P: [3 d, y* q! X
    ) g" B$ S" e& A+ k+ O            <!--  下面是所有需要自动创建事务代理的bean-->
    6 N9 ]& F8 F  R0 |# ]; k( n
    * W' q0 Y' C# ~$ a" W7 c4 R/ }            <list>
    # v2 b5 b/ q4 F# A+ E: W, |3 q; K" V8 `" w+ A# H
                    <value>us</value>
    * @/ L4 v4 N' z. n0 }) o( C  g  y% O, t) X
                </list> # u8 V# Y' c( j( O5 ?& N0 L
    ) n( L( ]% ^( C: ^" y9 S, x
                <!--  此处可增加其他需要自动创建事务代理的bean-->
    ' g2 P1 f- }3 J- Q) ]# b6 g
    / j% A& e9 ~: M4 T        </property> 9 P* Q4 R& `4 J* s% n1 F

    , k9 B! }% ~* A6 M& `  j        <!--  下面定义BeanNameAutoProxyCreator所需的事务拦截器-->
    # |" b, L! Q9 @9 T0 @5 ?# s- P1 L
    7 w6 o+ Y6 E  A: q8 N6 O4 Q7 s        <property name="interceptorNames">
    ' [' Q  I2 `" U% u" l7 m' t5 j' ]2 F+ P) r3 L! k, B, O
                <list>
    ( @/ Q8 w1 I4 Z* T7 q9 L) n# l/ m, O3 p2 B6 @
                    <!-- 此处可增加其他新的Interceptor -->
    ' q' \3 _/ h4 L* {& F% |
    7 V% c7 K; @) N. |( U1 _- e, j                <value>transactionInterceptor</value>
    - v" q$ T" z" B/ l+ A+ X6 K, j4 l# y& H/ d
                </list> & A, E* U6 H6 H. w$ G1 v7 Z! F

    , P& [( F. ?/ X+ X4 K        </property> 9 [1 ^7 Z# Z# q5 U3 `7 U
    * L/ Y  j3 U3 F2 M" w! x1 ~
    </bean>
    / y: v1 |6 B7 w$ P# k( F1 O' w' ]0 e% B" _) c& L
    然后我们在程序中调用时应如下:
    , N1 U; S# ?5 D6 W, s9 l3 [7 n1 M4 g9 h" A7 t
    UserService us = (UserService) app.getBean("us");
    + F7 P  E: Z' `0 M7 W, s) S$ @, w& A( r) K* H7 G" L  L
    注:注意与上面使用TransactionProxyFactoryBean时的调用区别,此处我们用getbean时直接取原服务层对象的id,不需要去配置目标bea,这也正是 + m% D- i: ?# R, j. J! v& b. f& ]
    , F/ O. C9 ?4 T2 I/ Y
    BeanNameAutoProxyCreator(根据bean名称自动代理)的含义所在
    5 Q1 r* ^$ R  h* i  {' {' Z
    - N/ ^" y5 `% i$ I0 a3 I4 _
    0 Y6 a. {1 A* F3 ?
    - ?5 B2 x) x9 [6 I% n/ W) p# m附录: # e( Q9 D' F4 O  l" ^" q0 w' h$ t
    : \) O  y6 _- B6 S
    1、关于hibernate的属性详解:
    . b7 @1 a- B0 v, a
    0 V$ s( S+ V1 S) _3 p+ L<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> 8 H+ z8 \9 z5 p, o
    ' b2 q8 G" M$ G4 ~
    <!-- 以下配置都是使用 jdbc.properties 属性文件中的配置,而之所以可以这样写,就是因为有 属性占位符配置的原因 -->
    3 s6 y( J' s# F3 V9 }
    % }# v; o" U9 ], `<property name="driverClass" value="${jdbc.driverClassName}"/>   ~8 q+ D9 ?! X. X

    8 G1 p! K. z5 S) f/ B6 f2 H<property name="jdbcUrl" value="${jdbc.url}"/>
    , Y: i+ [# m; p9 B" B% f  ]
    , k+ t. f+ B& J<property name="user" value="${jdbc.username}"/> 9 K/ X2 S( n+ |9 a

    / O6 M7 v1 f% h. s, U( \. ?<property name="password" value="${jdbc.password}"/>
    8 j* s; j' ~, ]1 D6 b- m# D1 Q1 a" X  @' z* U& n) F1 g( X0 W
    <!-- 连接池维持的最小的连接个数 --> : Z' _' |) {0 G/ @9 b1 \9 F" S
    # H( O5 u! i3 G6 m) {
    <property name="minPoolSize" value="5"/>
    8 m7 q. Z' r4 k; k; Y- I( P& S9 j" R+ }9 Y- L- ~/ T+ X6 Y
    <!-- 连接池维持的最大的连接个数 -->
    & P' M+ S+ l3 ~& ?* l% y; Q8 x' D6 i' E% ~& j! Z, D
    <property name="maxPoolSize" value="20"/>
    + H" y% {. ?8 {- [9 X. L, _+ T; [( L' W) V; G5 E7 c( \1 F3 E
    <!-- 最大空闲时间, 当某个连接在这个时间内没活动后将从池中移除,前提是池中至少多于最少的连接数: minPoolSize --> 2 m0 W9 w2 `, L7 y
    6 C! v: r2 V. R2 M) Q- }4 Y
    <property name="maxIdleTime" value="1800"/> ) P( D" W3 b2 d2 e! c4 F* `

    ; R; Y, Q" X3 a7 z<!-- 为加强准备语句的执行性能,此参数指定被缓存的 PreparedStatement 的个数 -->
    * V, U; C! y$ r0 W
    ; K: P/ Z, u1 v- b- s<property name="maxStatements" value="50"/>
    . [% y, e' s, u) }  l3 v+ ]
    $ Q% k( f9 f' P1 b+ [0 P</bean> 8 u$ G; O$ u* L. z
    & Q6 b% W3 u' A5 y, q* x

    4 R5 E$ l' H0 Z# e: Z7 j6 g8 y$ A* M5 {6 E/ Y% ~: {
    Hibernate 会话厂 SessionFactory
    # b. a+ ?. j, m, K: y( u7 F& p; D1 e! u5 I' J1 Q9 M
    Session 就是用于每次与数据库会话的,因此需要: ! v7 }/ B! a1 S  b' T" L

    9 C0 \6 c* F6 O( q; N数据库的配置参数,这些参数就是 上面的数据源指定的! 因此我们只需引用即可: ref="dataSource";
    % {, j- r" N7 n( L0 c" i; L, r
    * ~0 X+ f& z- Q3 r8 l6 X实体映射配置 hibernate.cfg.xml 配置
      C: n2 J3 W0 U7 ~- ]0 E5 ~/ D$ X3 u' i5 Q/ N" p4 B/ U) t
    结果缓存配置(这里使用的是开源的 ehcache) 6 H, v) V) h% j5 A3 n- h
    $ C; j, ^2 O  A

    * n6 ^( c" D( w8 e' k( e' M7 c
    * j. Z7 o$ o, f2 H$ [+ D<!-- Hibernate SessionFactory -->
    - @& L& s/ K/ K; K5 U; E/ J7 j7 P
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> ' M- v0 t6 v* n

    8 @, t. D$ z- F. B. g# r<!-- 引用前面定义的数据源 -->
    , m( o/ M# _3 }; `: `3 {& A# u# O( i1 n3 z0 e
    <property name="dataSource" ref="dataSource"/>
    . ^: z" ^# X* }$ ^  C$ y8 r
    ; B5 f! A& A, ]( S2 f& ~) s) g<!-- 所有实体映射文件列表, 所有的 hbm.xml 文件 -->
    : f$ [# Q% @  m  D/ T  O3 Z' K( f( a5 a0 \) c; Q% e  j
    <property name="mappingResources"> ; x1 n8 v) x2 S
    3 x, r9 u$ c6 p* H( E! f' }
    <list> . l; e& L/ l/ C* u- K" N$ I

    1 B5 i, I. w+ b' H$ ?" V: ^" A<value>org/springframework/samples/jpetstore/domain/Account.hbm.xml</value> 8 l$ L2 v( m8 \# Z; @  A8 m0 o

    1 T* A2 ~; ^5 v<value>org/springframework/samples/jpetstore/domain/Banner.hbm.xml</value>
    % V  L) j, m. u; y* A8 \( [* |/ I4 c* c, ~5 S- y
    <value>org/springframework/samples/jpetstore/domain/Category.hbm.xml</value>
    ) ?  b4 D6 I2 `3 Z% h0 E. o/ l
    ) I6 C0 S- _# q6 N' `' b<value>org/springframework/samples/jpetstore/domain/Inventory.hbm.xml</value>
    3 ?( E2 `) S# N( z# u" U6 I! Z( W' ]
    <value>org/springframework/samples/jpetstore/domain/Item.hbm.xml</value> 6 w  J+ n6 g) {- C+ a

    $ K3 Y/ @" d) ^1 a) T<value>org/springframework/samples/jpetstore/domain/LineItem.hbm.xml</value> 5 ]: t4 U7 L' W* J2 Q6 ^
    2 ~- R6 Q9 w5 s0 E. |
    <value>org/springframework/samples/jpetstore/domain/Order.hbm.xml</value> & j- [+ Z6 F7 E3 W' [/ F/ S
    0 I& _2 |' I4 S( t4 d6 E7 S1 R
    <value>org/springframework/samples/jpetstore/domain/Product.hbm.xml</value> 5 z. V1 k7 C8 G9 j7 x& H
    3 h& }5 {' A; F$ e/ s. i, l  m
    <value>org/springframework/samples/jpetstore/domain/Supplier.hbm.xml</value> ( K2 ~  l' @4 x1 N' F3 p, _
      J& h/ P9 ^5 M% J
    </list>
    ( {6 n  f) z6 }( _5 F
      w; o: Y9 A" P$ M</property>
    . }+ ~" q" n$ W) e/ @) q
    9 L6 l; ?, [5 ?! v<!-- 传统上的 hibernate.cfg.xml 文件的参数放在这里 -->
    5 D$ @( c- K9 i2 q( q0 m- D
    # H9 r) ?1 h' F# I8 S<property name="hibernateProperties"> - L7 O; T. M3 J8 k) u" n; W
    5 Y: b6 E, g5 `1 R' G
    <props> ; l& Y# @$ u/ G; _7 r/ l# j) o
    , T. y. |1 m) f" W2 U/ s# y# H4 e' g
    <!-- 指定数据库方言 -->
    ) L/ R9 w0 ~! a% z+ g. {
    , S0 l9 k+ l8 V<prop key="hibernate.dialect">${hibernate.dialect} 6 i3 u, X0 r, A( G& p
    4 a! ~, n3 F  N" L! g4 V6 b
    </prop>
    # [4 f7 {' [% j3 k& _$ ]& r7 K9 W* T+ U: T; d" H
    <!-- 是否在日志中输出所有Hibernate与数据库交互的SQL语句 --> ( H  i& ?! w# l. v4 y) t+ f
    ; J+ `/ m/ H2 ~7 n
    <prop key="hibernate.show_sql">true</prop>
    5 O% x7 E  a/ G, J1 L
    * b8 N3 M7 N+ F% s7 _0 j<!-- 是否在日志中输出的SQL 语句格式化成易读形式 --> & ?. V+ A5 d6 Z7 R' S6 j( N: i

    , b9 R( o2 e7 a<prop key="hibernate.format_sql">true</prop>
    4 F! |, e# _% G7 E; n5 J- V. a
    ( p7 C1 V# d/ j* {<!-- 是否显示统计形式,一般在测试阶段使用 --> & Q7 ?  b0 p% K) X; P+ @- b

    * A; P; _/ x% y8 d+ }<prop key="hibernate.generate_statistics">true</prop>
    & }5 }' x+ ?: a% h0 t
    - k, T9 X- |4 ?<!-- 对于级联查询,一次性获取的级联深度, @todo 需进一步研究 --> ' E! L- `: O* N! r9 j" Y9 Y
    + T2 d  z' g. N. J- t% W
    <prop key="hibernate.max_fetch_depth">2</prop>
    - ~& E' M/ m$ O
    4 O0 L* O( f) s. A1 [<!-- 7 n+ C! S6 [$ c( C
    : H, k, w, `1 ^; T; _' U
    Fetch Size 是设定JDBC的Statement读取数据的时候每次从数据库中取出的记录条数,一般设置为30、50、100。
    # t$ r  e' ?$ m/ F% }2 a$ B: C2 a; I* X, |3 B6 P. S6 p; h9 s
    Oracle数据库的JDBC驱动默认的Fetch Size=15,设置Fetch Size设置为:30、50,性能会有明显提升,如果继续增大, 7 L- l: I* K+ i! X, z7 f; t
    2 ~* z9 W5 Q' O) ]  h8 f' W
    超出100,性能提升不明显,反而会消耗内存。 7 h- k$ C+ p6 o: Z" c' i6 I& l6 ^

      U& y/ H9 S( o; X" a6 c-->
    ( r1 c" y/ p: q9 x# A8 y" }+ i/ R% k0 l+ @
    <prop key="hibernate.jdbc.fatch_size">100</prop>
    , p* K4 v' u" d* i9 N0 C
    / e3 p8 o5 ]( D<!-- 9 D4 w7 y+ C7 q! S, l% @

    . W& d. S. @. X) k/ X不必等到累计到50个SQL之后才执行.只要事务commit后,不管缓存中有多少条sql语句都要执行.
    6 z- z! t" [* C6 a+ \# N
    . R+ ?5 A8 V& y% I" O1 Khibernate.jdbc.batch_size参数只是设定一次最多可以提交多少sql语句的上限,提高sql语句的执行效率
    ; J8 w6 L8 H5 ?6 e% G$ U+ V* o
    $ D2 i  X, Q: f8 V( b3 F! d9 l2 ~) W-->
    ' a$ p/ P8 c( T7 l- o, C' F3 u# D4 x; c5 J8 p. ?
    <prop key="hibernate.jdbc.batch_size">50</prop>
    ) W' \/ }% D% k! X- ^2 U* w1 W( B* Q# \, R2 A) X9 @7 T" H
    <!--
    ! {8 `, m2 j( {3 u; V" ]% b/ H% {* A' U1 e. w) M% Z; b3 l1 \
    (1)create 在每次SesstionFactory 构建时(一般是应用重启时,或者伴随着应用服务器重启时),先将之前数据库中的所有数据全 ; ]/ ~5 I# J& y
    + V  L: d& G( r1 q* \
    部清空,后紧跟着根据所有的hbm.xml 映射文件重新创建新的数据库表 , Q1 v( A0 [7 D6 m; I
    % i# X$ L' @* h8 ~0 v4 E% {8 i

    4 L- r% g0 @2 ^( ^4 L' l# E8 y/ i7 Q: V- J6 e  I& l
    (2)create-drop 除了create 的所有含义之外,在每次应用的退出前,将进行一次数据空清空。因此这个配置将有两次清空操作,
    ! E/ P2 D, j3 d, f: h& u  }
    # u5 j1 L8 x: ~4 I! t一次是退出,一次是启动时。 * u1 i$ ]7 r4 q- i: u$ O

    * ~, D; M$ R& n5 s5 B
    ! V9 i# f% i+ C) q" T/ z! m! Y1 Q* R& y* O5 I2 Q0 ~; }# K
    (3)update
    9 S* _$ I  N4 @# x$ Y. [) F; j# t4 S$ b0 c) j/ J
    如果在开发阶段理发了实体对象的映射文件(hbm.xml) 的定义后,此配置将后台的数据库表进行更新(如增加表的列)
    , ]$ G) }1 V7 d( i- R! }: o
      S* [" w  ~! J8 z: U2 q# R# F) J/ ~/ f  n$ i7 V

    $ Z# H4 B8 Q  U1 a# ]" `) A(4)validate
    1 a8 a3 Q% K8 a( f: D# @" B$ j0 D; H" [+ U2 [
    用于校验现有的表与现有的配置是否一致。
    + L) V1 G  ]; i! R7 j% b1 z
    $ M6 C2 }' R' M- Z7 j8 Z. h* q--> * `$ S& w7 D$ S. s

    $ ?5 ?$ }. {" T0 R<prop key="hibernate.hbm2ddl.auto">update</prop>
    # X" Q9 [) U! [% b3 {+ g
    . O8 @( Z. d, j# H9 Z<!-- 见下面的解释 -->
    & [; |7 w7 a) g# \) K( B+ {
    1 t6 O" y9 q7 T2 q8 H<prop key="hibernate.hbm2ddl.auto">update</prop> 9 \- k0 J6 Z6 y

    4 n+ v8 y9 O" [. {0 \1 O; z9 _<!--结果缓存配置:- 将ehcache.xml 置于 classpath 中- 如果不设置“查询缓存”, * Y8 L% A+ }; X  a* Q, w9 @/ v( Y; W

    3 H9 e' M% D9 @. }& @那么hibernate只会缓存使用load()方法获得的单个持久化对象,如果想缓存使用findall()、 list()、 4 B6 ^0 a+ z2 m( j* L6 T
    " Z' C& h& R, v1 m7 Y
    Iterator()、createCriteria()、createQuery()等方法获得的数据结果集的话,就需要设置
    9 ?' Z' w9 |6 }6 \! X0 l0 O
    * \3 s7 y# M4 P# F, ihibernate.cache.use_query_cache true 才行- 在Hbm文件中添加<cache usage="read-only"/>-
    2 K3 t2 Q  \& k* E$ @. x2 o$ s) B0 V3 a& F. @# N+ S1 y
    如果需要“查询缓存”,还需要在使用Query或Criteria()时设置其setCacheable(true);属性-->
    7 @9 b4 R5 c$ ]: j% L
    " }" f7 J' l. F( l2 m5 i<prop key="hibernate.cache.use_query_cache">true</prop> - Q) Z' D* A; H7 ]  L

    9 ?: j9 a7 ?, ~: u. \<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop> 1 F% W/ D) |6 X6 {  `5 G& z

    # f) a6 U$ X% l! {</props>
    + t" o  |) y3 Y6 A
    ( `7 z1 C0 h/ C! \5 c; @: I- k</property>
    5 a2 J% }/ I, v' {* x/ M( ~) \, {  x4 ^5 W
    <!-- 为解决 merge()方法语义的歧义 @todo 以后进一步解析或者你可以看一下相应的文档 --> 1 C$ Z0 }7 g; c7 ]4 k* P0 U

    , R9 v" O, l# H, X, m<property name="eventListeners"> ' D, x' A; H$ k7 i1 p! W0 [

    4 I# E/ @8 a3 E6 R! B: {2 z! x8 ~<map><entry key="merge"> 8 o7 X' a8 D5 o  V

      f  K1 a  f+ a0 N<bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/> ) T0 N# k8 p4 ?% z/ y
    - O$ P9 m$ n" _0 u
    </entry></map> ' j; k' x1 p& M" B
    , Y3 k1 n- I, X( k
    </property> , S1 p- ]" [- o% u# Z- z

    5 o7 I# M: Z  K' v* U+ l) w7 D</bean> ) K. ]2 N. t7 }, Z5 s

    % O" {! x  v- O5 \$ a) M' Q3 u! ]) d& h/ d; m

    1 K( O4 e% w( }& Z, D. m2、Spring的transactionAttributes
    1 k/ G# p1 c$ l; m7 l3 D0 a! x6 b* {2 K/ x+ l! j: X
    2 X0 I' F) ~2 G! b
    * B7 r8 }3 a& D& R2 u
    PROPAGATION_REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 + g' ?. x( L, a9 X+ r3 N( ?) w
      d+ V/ l2 S8 [7 r% B  v/ W  Q' E
    PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。 3 E# ^* h9 d+ L* d3 Z
    8 A9 E; T7 {; n; D! n; x8 [
    PROPAGATION_MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。 4 _" |) ?) K3 X7 [9 o6 A# o& ?

    2 ^4 X" ^: B, O# s/ p! [; tPROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。 / t; N) ?% E; v" a

    * a" d+ E# n$ e% fPROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 8 `6 G+ Z+ s5 y# A
    0 T6 L  ^! H, }# i; R
    PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
    + h3 m( j' O+ o) P8 I" y
    " y$ l( S2 |( m/ q  W" l% p, l! v% KPROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
    回复

    使用道具 举报

    1

    主题

    0

    听众

    9

    金钱

    一袋弟子

    该用户从未签到

    板凳
    发表于 2014-09-07 19:14:21 |只看该作者
    有下载就好了 附件
    回复

    使用道具 举报

    快速回复
    您需要登录后才可以回帖 登录 | 立即注册

       

    关闭

    站长推荐上一条 /1 下一条

    发布主题 快速回复 返回列表 联系我们 官方QQ群 科帮网手机客户端
    快速回复 返回顶部 返回列表