dev2dev.bea.com.cn
首页 资源中心 dev2dev学堂 在线技术论坛 专家Blog User Group CodeShare

如何理解嵌套事务(Nested Transaction)

2008-03-04 13:53:49 | 评论 (0) | 被访问(228)次

黄兆勤
  David Turing对一些安全问题感兴趣,如Java Security、WS-Security和PKI。


目前,似乎很少有支持嵌套事务的中间件,但嵌套事务确实存在。
假定有Method A, Method B, Method C
A 调用 B,C

ServiceHost {    
        
    
/**   
     * 事务属性配置为 PROPAGATION_REQUIRED   
     
*/   
    
void invoke() {    
      try{
           ServiceA.invoke()
      } 
catch (Bussiness.A.Exception) { 
           abort()
      }

        
try {    
            ServiceB.invoke();    
        } 
catch (Bussiness.B.Exception) {    
            ServiceC.invoke();
        } 
catch (Bussiness.C.Exception) {    
            ServiceD.invoke();
        } catch (Bussiness.D.Exception) { 
           abort()
      }

  
        
try{
           ServiceE.invoke()
        } 
catch (Bussiness.E.Exception) { 
           ServiceF.invoke()
        }catch (Bussiness.F.Exception) { 
           abort()
      }


    }    
   

 

ServiceA {    
        
    
/**   
     * 事务属性配置为 PROPAGATION_NESTED, 
     × 即该事务需要被嵌套   
     
*/     
    
void methodA() {    
    }    
        
}

 

ServiceA, ServiceB, ServiceC, ServiceD, ServiceE, ServiceF都配置为PROPAGATION_NESTED
通过这样的嵌套规约,我们可以满足业务完整性的需求,一个ServiceParent 业务,只允许出现A-B-E , A-B-F, A-C-E, A-C-F, A-D-EA-D-F的组合,其他组合,如A-B-C, A-E, B-F都是不允许的。
 
术语上,ServiceA, B, C, D, E, F的事务均是ServiceParent事务的子事务,现在,是ServiceParent嵌套ServiceA-F,且嵌套事务的几个特性如下:
1, 假定子事务(ServiceA-F)处于活动状态(active),则parent事务(ServiceParent)不能执行任何其他操作,父事务只能commit事务,abort事务以及创建更多其它子事务。
2, 若子事务(ServiceA)被提交了,此时父事务则能够看到子事务做出的任何修改,这些修改,对其他子事务来说是隐藏的,直到父事务提交为止。
3, 同样地,如果被嵌套的事务ServiceA被回滚了,则它也不会对父事务有任何影响,且父事务servieParent也不会看到ServiceA曾经修改过的数据。
4, 最终父事务提交、回滚才会决定到子事务的提交、回滚。表达的形象点,若ServiceA“提交”后,ServiceParent却因为Service B/C/D都无法成功执行,ServiceA会回滚。这种做法依赖于JDBC 3.0 SavePoint技术。
5, 嵌套子事务提交后,它对DB的锁其实并没有释放,这些锁的控制权被转交给父事务,直到父事务提交(或回滚)后,锁才会真正释放
6, 目前,嵌套的深度不收控制,也就是,我们可对method进行以深度嵌套。
 
 
           
      现在,我们略略了解一下JDBC SavePoint技术,它给予了我们这样的能力,在一个事务里面,我们能够将已经提交的事务状态,恢复到一个事务commit以前的任意定点(这个点就是SavePoint)
            举个例子,假设我们面临这样一种情况,methodA是运算代价非常大的事务操作,methodB, methodC都是轻量级的事务,我们需要执行这样一个事务Tx={methodA->methodB->methodC}
           没有SavePoint之前,如果methodA执行成功,但是恰恰methodB失败了,那么methodA所有成果必须回滚,methodC也别想执行了,因为methodAmethodBmethodC都在同一个Tx事务中;JDBC3.0SavePoint技术为我们提供了一个无需回滚MethodA的折衷办法,可以让我们在保留methodA的成果的同时,仅仅回滚methodB,然后继续执行methodC
      回滚到SavePoint的代码类似于:

 

Statement stmt = conn.createStatement();
int rows = stmt.executeUpdate("INSERT INTO TAB1 (COL1) VALUES " +
"(’FIRST’)");
// set savepoint
Savepoint svpt1 = conn.setSavepoint("SAVEPOINT_1");
rows 
= stmt.executeUpdate("INSERT INTO TAB1 (COL1) " +
"VALUES (’SECOND’)");

conn.rollback(svpt1);

conn.commit();


Tags: transaction
文章评论:(以下网友留言只代表个人观点,不代表BEA观点和立场)
暂时没有评论!

2008年03月

          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            
RSS订阅

黄兆勤's Blog搜索