spring异常抛出触发事务回滚策略导读

转载 2012年03月30日 13:11:47
[转自:http://cn.dydou.cn/ws/201108/0QQI132011.html]
spring异常抛出触发事务回滚策略导读:Spring、EJB的声明式事务 默认 情况下都是在 抛出unchecked exception 后才会触发事务的回滚 测试用业务逻辑方法: Java代码 /** *如果在spring事务配置中不为切入点(如这里的切入点可以定义......

--------------------------------------------------------------------------------
Spring、EJB的声明式事务默认情况下都是在抛出unchecked exception后才会触发事务的回滚 

测试用业务逻辑方法: 

Java代码  
1./** 
2. * 如果在spring事务配置中不为切入点(如这里的切入点可以定义成test*)配置事务在什么情况下回滚(格式:-引起回滚的异常类型) 
3. * 则spring默认只会在service方法抛出unchecked exception才会触发回滚 
4. */  
5.public class TestServiceImpl extends Service implements TestService {  
6.  
7.    /** 
8.     * 测试spring异常触发事务回滚的service方法 
9.     */  
10.    public void testAddPerson(String name) throws Exception {  
11.        TestPerson p = new TestPerson();  
12.        p.setName(name);  
13.        this.getHibernateGenericController().save(p);  
14.          
15.        /* 
16.         * 制造RuntimeException 
17.         * 在spring默认的异常回滚策略下,该异常的抛出会触发事务的回滚,数据不会被插入 
18.         */  
19.        throw new RuntimeException("抛出个运行时异常");  
20.          
21.        /** 
22.         * 同样是unchecked exception,spring默认的异常回滚策略下Error的抛出也会触发事务的回滚,数据不会被插入 
23.         */  
24.//      throw new Error();  
25.          
26.        /** 
27.         * 即使是在spring默认的异常触发事务回滚策略(unchecked exception触发回滚)下, 
28.         * 如果使用try-catch捕获抛出的unchecked异常后没有在catch块中采用页面硬编码的方式使用spring api对事务做显式的回滚,则事务不会回滚,数据被插入 
29.         * “将异常捕获,并且在catch块中不对事务做显式提交=生吞掉异常” 
30.         */  
31.//      try {  
32.//          throw new RuntimeException("这个抛出的运行时异常会被try-catch捕获");  
33.//      } catch(Exception e) {  
34.//          System.out.println("捕获到异常: " + e.getMessage());  
35.//      }  
36.          
37.        /** 
38.         * 因为Exception类是个checked exception,所以这里抛出的异常不会触发事务的回滚,数据被插入 
39.         */  
40.//      throw new Exception("a Exception instance");  
41.          
42.        /** 
43.         * 该BaseException继承自Exception,也为checked exception,抛出它后: 
44.         * spring默认的回滚策略下,事务未回滚, 数据被插入; 
45.         * 在TransactionProxyFactoryBean的transactionAttributes中配置 
46.                    <prop key="test*"> 
47.                        ... ...,-BaseException 
48.                    </prop> 
49.            后,事务回滚,数据未被插入 
50.         */  
51.//      throw new BaseException("一个BaseException");  
52.    }  
53.  
54.}  
/**
 * 如果在spring事务配置中不为切入点(如这里的切入点可以定义成test*)配置事务在什么情况下回滚(格式:-引起回滚的异常类型)
 * 则spring默认只会在service方法抛出unchecked exception才会触发回滚
 */
public class TestServiceImpl extends Service implements TestService {

	/**
	 * 测试spring异常触发事务回滚的service方法
	 */
	public void testAddPerson(String name) throws Exception {
		TestPerson p = new TestPerson();
		p.setName(name);
		this.getHibernateGenericController().save(p);
		
		/*
		 * 制造RuntimeException
		 * 在spring默认的异常回滚策略下,该异常的抛出会触发事务的回滚,数据不会被插入
		 */
		throw new RuntimeException("抛出个运行时异常");
		
		/**
		 * 同样是unchecked exception,spring默认的异常回滚策略下Error的抛出也会触发事务的回滚,数据不会被插入
		 */
//		throw new Error();
		
		/**
		 * 即使是在spring默认的异常触发事务回滚策略(unchecked exception触发回滚)下,
		 * 如果使用try-catch捕获抛出的unchecked异常后没有在catch块中采用页面硬编码的方式使用spring api对事务做显式的回滚,则事务不会回滚,数据被插入
		 * “将异常捕获,并且在catch块中不对事务做显式提交=生吞掉异常”
		 */
//		try {
//			throw new RuntimeException("这个抛出的运行时异常会被try-catch捕获");
//		} catch(Exception e) {
//			System.out.println("捕获到异常: " + e.getMessage());
//		}
		
		/**
		 * 因为Exception类是个checked exception,所以这里抛出的异常不会触发事务的回滚,数据被插入
		 */
//		throw new Exception("a Exception instance");
		
		/**
		 * 该BaseException继承自Exception,也为checked exception,抛出它后:
		 * spring默认的回滚策略下,事务未回滚, 数据被插入;
		 * 在TransactionProxyFactoryBean的transactionAttributes中配置
					<prop key="test*">
						... ...,-BaseException
					</prop>
			后,事务回滚,数据未被插入
		 */
//		throw new BaseException("一个BaseException");
	}

}


关于TransactionProxyFactoryBean的transactionAttributes中字符串的值(定义自TransactionAttributeEditor):


is a transaction attribute descriptors that parsed via TransactionAttributeEditor 

见本博客:

http://wuaner.iteye.com/admin/blogs/567792 


单元测试代码:



Java代码  
1.public class TestSpringDefaultRollback extends TestCase {  
2.  
3.    private static ApplicationContext context = new ClassPathXmlApplicationContext("resource/xxx/applicationContext.xml");  
4.    public void testDefaultRollback() throws Exception{  
5.        TestService testServiceImpl = (TestService)context.getBean("testService");  
6.        testServiceImpl.testAddPerson("张三");  
7.    }  
8.}  
public class TestSpringDefaultRollback extends TestCase {

	private static ApplicationContext context = new ClassPathXmlApplicationContext("resource/xxx/applicationContext.xml");
	public void testDefaultRollback() throws Exception{
		TestService testServiceImpl = (TestService)context.getBean("testService");
		testServiceImpl.testAddPerson("张三");
	}
}



将异常捕获,并且在catch块中不对事务做显式提交(或其他应该做的操作如关闭资源等)=生吞掉异常 


spring的事务边界是在调用业务方法之前开始的,业务方法执行完毕之后来执行commit or rollback(Spring默认取决于是否抛出runtime异常).



如果抛出runtime exception 并在你的业务方法中没有catch到的话,事务会回滚。



一般不需要在业务方法中catch异常,如果非要catch,在做完你想做的工作后(比如关闭文件等)一定要抛出runtime exception,否则spring会将你的操作commit,这样就会产生脏数据.所以你的catch代码是画蛇添足。


由此可以推知,在spring中如果某个业务方法被一个 

Java代码  
1.try {  
2.    //bisiness logic code  
3.} catch(Exception e) {  
4.    //handle the exception  
5.}  
try {
	//bisiness logic code
} catch(Exception e) {
	//handle the exception
}
整个包裹起来,则这个业务方法也就等于脱离了spring事务的管理,因为没有任何异常会从业务方法中抛出!全被捕获并吞掉,导致spring异常抛出触发事务回滚策略失效。 
不过,如果在catch代码块中采用页面硬编码的方式使用spring api对事务做显式的回滚,这样写也未尝不可。 


 

spring trigger transaction rollback exception thrown Strategy
 

Spring, EJB's declarative transaction by default, throw an unchecked exception are only triggered after the transaction rollback 

Test business logic methods: 

/**
 *  If you do not spring transaction configuration as a starting point, such as the starting point of the test can be defined as  * ) Configuration transaction is rolled back (in the format:  - The type of exception caused the rollback)  
 *  The spring default only service method throws an unchecked exception triggered rollback  
 */
public class TestServiceImpl extends Service implements TestService {

        /**
         *  Test spring exception triggered the transaction to roll back the service method  
         */
        public void testAddPerson(String name) throws Exception {
                TestPerson p = new TestPerson();
                p.setName(name);
                this.getHibernateGenericController().save(p);
                
                /*
                 *  Manufacture of RuntimeException  
                 *  In spring the default exception rollback strategy, the exception thrown to trigger a transaction rollback  , Data will not be inserted  
                 */
                throw new RuntimeException(" Throw a runtime exception  ");
                
                /**
                 *  The same is unchecked exception, spring default exception rollback strategy under the thrown Error can also trigger a rollback of the transaction, the data will not be inserted  
                 */
//              throw new Error();
                
                /**
                 *  Even in spring default exception triggered transaction rollback strategy (unchecked exception triggered rollback),  
                 *  If you use try  -catch Capture of unchecked exception thrown when no in the catch block in the page hard-coded to use spring API do explicit rollback transaction, the transaction will not be rolled back, the data is inserted  
                 *  The exception to a capture  , And in a catch block to do an explicit commit transaction  = Eat out exception "  
                 */
//              try {
//                      throw new RuntimeException(" This throws a runtime exception is try  -catch Capture  ");
//              } catch(Exception e) {
//                      System.out.println(" Caught exception:  " + e.getMessage());
//              }
                
                /**
                 *  Because the exception class is a checked exception, so it throws an exception of does not trigger a rollback of the transaction, the data is inserted  
                 */
//              throw new Exception("a Exception instance");
                
                /**
                 *  The BaseException inherited from Exception, as well as checked exception thrown when it  :
                 * spring The default rollback strategy, the transaction is not rolled back, the data was inserted;  
                 *  In the configure TransactionProxyFactoryBean transactionAttributes  
                                        <prop key="test*">
                                                ... ...,-BaseException
                                        </prop>
                         After the transaction is rolled back, the data has not been inserted  
                 */
//              throw new BaseException(" A BaseException  ");
        }

}



Unit test code:



public class TestSpringDefaultRollback extends TestCase {

        private static ApplicationContext context = new ClassPathXmlApplicationContext("resource/xxx/applicationContext.xml");
        public void testDefaultRollback() throws Exception{
                TestService testServiceImpl = (TestService)context.getBean("testService");
                testServiceImpl.testAddPerson(" Smith, John  ");
        }
}


Catch the exception and the catch block in the transaction do not explicitly presented (or the other should do the operation, such as closure of resources, etc.) = Health swallow an exception 


spring of the transaction boundaries are started before the business method is called, the business method implementation of the completion of the subsequent implementation of the commit or rollback (Spring default depends on whether the runtime throws an exception).



If you throw runtime exception in the way your business does not catch that, then the transaction will be rolled back.



In general do not need to catch an exception in business method, If I have to catch, in the work you want done (such as closing documents, etc.) must throw runtime exception, otherwise the spring will put your operation commit, that would create dirty data. So you catch code is superfluous.


From this we can deduce that if a business in the spring in the method is a 

try {
        //bisiness logic code
} catch(Exception e) {
        //handle the exception
}

The whole package together, then this business method is the same as out of spring management of its affairs, since no exceptions will be thrown from a business method! Were all captured and eaten, leading to an exception thrown spring trigger transaction rollback strategy for failure. 
However, if the catch block the use of hard-coded pages use spring api to do the transaction explicit rollback, so that was also something that can not be. 

本篇文章来源于 中文DY豆-cn.dydou.cn 原文链接:http://cn.dydou.cn/ws/201108/0QQI132011.html

相关文章推荐

Spring事务管理只对出现运行期异常进行回滚

使用spring难免要用到spring的事务管理,要用事务管理又会很自然的选择声明式的事务管理,在spring的文档中说道,spring声明式事务管理默认对非检查型异常和运行时异常进行事务回滚,而对检...

Spring事务为什么不会自动回滚?Spring事务怎样才会自动回滚?事务自动回滚条件及手动回滚

在此,首先我们要明确RuntimeException与Exception之间的关系与他们分别的含义:        ①在Java中异常的基类为Throwable,他有两个子类Exception与Er...

Spring配置事务 service 异常捕获回滚问题

1.首先来看一Spring配置事务的传播种类: Spring在TransactionDefinition接口中规定了7种类型的事务传播行为,它们规定了事务方法和事务方法发生嵌套调用时事务如何进行...

JPA事务和hibernate混合事务研究<一>

混合事务用起来确实是比较麻烦的事情,我也百度了下,基本上只看见了关于jdbc事务和jpa事务(hibernate事务)混合事务的介绍,以及用法,但是就是没有看到jpa事务和hibernate混合事务的...

如何修改request的parameter的几种方式

这篇文章仅仅用来参考,本身不想写,request之所以不想让你修改parameter的值,就是因为这个东西一般不然改,有人问我为什么不让改,表面上说我只能说这属于篡改数据,因为这个使用户的请求数据,如...
  • Aeroleo
  • Aeroleo
  • 2016年08月14日 16:02
  • 1383

Spring异常抛出触发事务回滚策略

Spring、EJB的声明式事务默认情况下都是在抛出unchecked exception后才会触发事务的回滚  测试用业务逻辑方法:    整个包裹起来,则这个业务方法也就等于脱离...

Spring事务异常回滚,捕获异常不抛出就不会回滚

最近遇到了事务不回滚的情况,我还考虑说JPA的事务有bug? 我想多了.......     为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志。但是这边情况来了,当这个方法异...

spring事务异常回滚,捕获异常不抛出就不会回滚

最近遇到了事务不回滚的情况,我还考虑说JPA的事务有bug? 我想多了.......     为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志。但是这边情况来了,当这个方法...

Spring事务异常回滚,捕获异常不抛出就不会回滚

最近遇到了事务不回滚的情况,我还考虑说JPA的事务有bug? 我想多了.......     为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志。但是这边情况来了,当这个方法...

十六、Spring事务异常回滚,捕获异常不抛出就不会回滚

最近遇到了事务不回滚的情况,我还考虑说JPA的事务有bug? 我想多了……. 为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志。但是这边情况来了,当这个方法异常时候 日...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:spring异常抛出触发事务回滚策略导读
举报原因:
原因补充:

(最多只允许输入30个字)