码迷,mamicode.com
首页 > 编程语言 > 详细

spring事务声明的几种传播特性

时间:2014-08-25 07:37:03      阅读:249      评论:0      收藏:0      [点我收藏+]

标签:style   http   color   java   os   io   for   ar   art   

近来遇到了一个spring业务致使的疑问,所以写了几个小程序了解了一下业务的传达特性,下面别离举比如别离看看业务的传达特性。

业务的几种传达特性
1. PROPAGATION_REQUIRED: 假如存在一个业务,则支撑当时业务。假如没有业务则敞开
Java代码 保藏代码
/**
* TransactionTestService test1和test2配有业务(PROPAGATION_REQUIRED) */
public interface TransactionTestService {
//业务特点 PROPAGATION_REQUIRED
public void test1() throws Exception{

澳洲保健品http://www.eget.com.au
国医一号http://www.tdhzp.com
号码大全http://www.haomad.com
临沂购http://www.shoudashou.com
avInfoTaskTunnel.insertAvInfoTask();
test2();
}
//业务特点 PROPAGATION_REQUIRED
public void test2() throws Exception{
avRequestTunnel.insertAvRequest();
throw new Exception();
}
}

/**
* main
*/
public class TransactionTestMain {

public static void main(String[] args) throws Exception{
TransactionTestService transactionTestService = (TransactionTestService)context.getBean("transactionTestService");
try {
transactionTestService.test1();
} catch (Exception e) {
}
}
}
上述代码中test1()和test2()都配有PROPAGATION_REQUIRED业务特点,test1()内部调用test2(),这样test1()和test2()办法将都处于同一业务傍边,当在test2()中抛出反常,会致使test1()和test2()办法中的业务都回滚。
可是,假如test1()办法对调用test2()时捕获反常,成果会是如何的呢? test1应该能正常写入没疑问,那么test2呢?
Java代码 保藏代码
//test1()中捕获test2()抛出的反常
public void test1() throws Exception{
avInfoTaskTunnel.insertAvInfoTask();
try {
test2();
}catch (Exception e) {
}

}
最后的成果test2()也将会正常的写入。本来,上面状况中假如仅仅test1()配有PROPAGATION_REQUIRED业务特点,test2()不装备任何业务特点,发作的成果也是共同的。上面的景象相当于:
Java代码 保藏代码
public static void main(String[] args) throws Exception{
Connection con = null;
try {
con=getConnection();
con.setAutoCommit(false);
transactionTestService.test1(); //test1()和test2()处于同一业务傍边
con.commit();
} catch (Exception e) {
con.rollback();
} finally {
closeCon();
}
}
上述test1()和test2()是同一个类的两个办法,那么要是它们处于不相同类呢?
Java代码 保藏代码
//main函数不变,test1()中调用test2()地方换成调用另一个类中配有PROPAGATION_REQUIRED业务特点的办法
//不对otherService.test2()捕获反常的景象就没必要说了,一定都回滚。
public void test1() throws Exception{
avInfoTaskTunnel.insertAvInfoTask();
try {
otherService.test2(); //PROPAGATION_REQUIRED业务特点
} catch (Exception e) {
}
}

//otherService.test2()
public void test2() throws Exception{
avRequestTunnel.insertAvRequest();
throw new Exception();
}
上述相同捕获了反常,可是成果会如何呢? 成果有点出人意料,与之前test1(),test2()处于同一类的景象不相同,这个时分,两个办法都将回滚,而且在调用test1()的地方会抛出下面反常。这是因为子业务在回滚的时分现已将主业务符号成了rollback-only,这样致使主业务在提交的时分就会抛出下面这个反常。 别的:假如otherService.test2()没有装备任何业务特点,那么test2()抛出反常的时分,将致使test1()和test2()都回滚。
Java代码 保藏代码
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
上述状况网上查询到一种处理办法是在transactionManager中将globalRollbackOnParticipationFailure 设置为false(默认是true)。可是这样又带来另一个疑问,子业务也给一并提交了(这个时分子业务发生反常,不想提交),详细的处理办法还没找到,可是我觉得不应该将这两个装备在同一业务中。
Xml代码 保藏代码
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">






2. PROPAGATION_SUPPORTS: 假如存在一个业务,支撑当时业务。假如没有业务,则非业务的履行
Java代码 保藏代码
//TransactionTestService test1()配有业务(PROPAGATION_SUPPORTS)
public void test1() throws Exception{
avInfoTaskTunnel.insertAvInfoTask();
throw new Exception();
}


/**
* main
*/
public class TransactionTestMain {

public static void main(String[] args) throws Exception{
TransactionTestService transactionTestService = (TransactionTestService)context.getBean("transactionTestService");
try {
transactionTestService.test1();
} catch (Exception e) {
}
}
}
TransactionTestService的test1()配有PROPAGATION_SUPPORTS业务特点,咱们晓得这种景象下假如配的是PROPAGATION_REQUIRED业务特点,那么test1()将新建业务运转,可是PROPAGATION_SUPPORTS特点不会新建,这种景象下,test1()办法将正常提交。那假如是外层业务配有业务呢?如下所示,此种景象test2()将处于业务傍边了。
Java代码 保藏代码
//PROPAGATION_REQUIRED业务特点
public void test1() throws Exception{
avInfoTaskTunnel.insertAvInfoTask();
test2();
}
//PROPAGATION_SUPPORTS业务特点
public void test2() throws Exception{
avRequestTunnel.insertAvRequest();
throw new Exception();
}

3. PROPAGATION_MANDATORY: 假如现已存在一个业务,支撑当时业务。假如没有一个活动的业务,则抛出反常。

Java代码 保藏代码
//景象1:PROPAGATION_REQUIRED业务特点 景象2:不配任何业务特点
public void test1() throws Exception{
avInfoTaskTunnel.insertAvInfoTask();
otherService.test2();
}
//otherService的test2()装备PROPAGATION_MANDATORY业务特点
public void test2() throws Exception {
avRequestTunnel.insertAvRequest();
throw new Exception();
}

//test1()处于景象2时抛出反常,test2()不能够提交,可是test1()却是能够成功提交的
org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation ‘mandatory‘
上述状况,当test1()处于景象1时,会是的test1()和test2()都处于业务傍边;test1()处于景象2时,就会抛反常,可是这个时分test2()不能够提交,可是test1()却是能够成功提交的。此外,还有一点,留意上述test2()是处于另一个类中的,假如是处于同一个类,那么PROPAGATION_MANDATORY不会因为外层是不是有业务而抛反常。
4. PROPAGATION_REQUIRES_NEW: 老是敞开一个新的业务。假如一个业务现已存在,则将这个存在的业务挂起。
Java代码 保藏代码
//景象1:PROPAGATION_REQUIRED业务特点 景象2:不配任何业务特点
public void test1() throws Exception{
avInfoTaskTunnel.insertAvInfoTask();
otherService.test2();
}
//otherService的test2()装备PROPAGATION_REQUIRES_NEW业务特点
public void test2() throws Exception {
avRequestTunnel.insertAvRequest();
throw new Exception();
}
上述状况,test1()处于景象2时test2()新建业务,这点没有疑问。那假如test1()处于景象1呢?也即是说test1()现已有业务了。成果是test2()处于新的业务中,怎样确定是处于新的业务中呢?看下面代码:
Java代码 保藏代码
//test1装备PROPAGATION_REQUIRED业务特点
public void test1() throws Exception{
avInfoTaskTunnel.insertAvInfoTask();
otherService.test2(); //PROPAGATION_REQUIRES_NEW业务特点
}

//otherService.test2()
public void test2() throws Exception{
avRequestTunnel.insertAvRequest();
throw new Exception();
}
假如是在同一业务中,那么景象将同于叙述PROPAGATION_REQUIRED特点时的景象,test1()和test2()都将回滚,而且抛出反常业务被打上rollback-only符号的反常。可是这儿,成果即是test2()回滚,test1正常提交,所以otherService.test2()处于新的业务中。留意:上述状况test2()也是另一个类的办法,假如归于同一类,也即是test1()和test2()处于同一个类,test1()中调用test2(),那么装备的PROPAGATION_REQUIRES_NEW将无效(跟test2()啥业务特点都没装备相同)。可是假如是main函数中直接调用test2(),那么仍是会起一个新的业务。
别的一种证实test1()和test2()处于不相同业务的办法是,在test2()不抛出反常,然后再test1()调用了test2()以后,抛出反常,最后成果是()回滚,test2()正常提交。

5. PROPAGATION_NOT_SUPPORTED: 老对错业务地履行,并挂起任何存在的业务。
Java代码 保藏代码
//test1装备PROPAGATION_REQUIRED业务特点
public void test1() throws Exception{
avInfoTaskTunnel.insertAvInfoTask();
otherService.test2(); //PROPAGATION_NOT_SUPPORTED业务特点
}

//otherService.test2()
public void test2() throws Exception{
avRequestTunnel.insertAvRequest();
throw new Exception();
}
假如otherService.test2() 没有装备业务特点,那么test2()抛出反常时,test1()和test2()都回滚。可是如今test2()装备了PROPAGATION_NOT_SUPPORTED业务特点,那么test2()将以非业务运转,而test1()持续运转在业务中,也即是说,此刻,test1()回滚,test2()正常提交。留意:假如test1()和test2()在同一类中,那么test2()的PROPAGATION_NOT_SUPPORTED失效。

6. PROPAGATION_NEVER: 老对错业务地履行,假如存在一个活动业务,则抛出反常
Java代码 保藏代码
//test1装备PROPAGATION_REQUIRED业务特点
public void test1() throws Exception{
avInfoTaskTunnel.insertAvInfoTask();
otherService.test2(); //PROPAGATION_NEVER业务特点
}

//otherService.test2()
public void test2() throws Exception{
avRequestTunnel.insertAvRequest();
throw new Exception();
}
//test1()装备PROPAGATION_REQUIRED业务特点, otherService.test2()装备PROPAGATION_NEVER业务特点,将抛下面反常:
org.springframework.transaction.IllegalTransactionStateException: Existing transaction found for transaction marked with propagation ‘never‘
当然上述状况,假如是test1()和test2()在同一类中,那么PROPAGATION_NEVER也将失效。

7. PROPAGATION_NESTED:假如一个活动的业务存在,则运转在一个嵌套的业务中. 假如没有活动业务, 则按TransactionDefinition.PROPAGATION_REQUIRED 特点履行
最简单弄混杂的本来是 PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED。PROPAGATION_REQUIRES_NEW 发动一个新的, 不依赖于环境的 "内部" 业务. 这个业务将被彻底 commited 或 rolled back 而不依赖于外部业务, 它拥有自个的阻隔规模, 自个的锁, 等等. 当内部业务开端履行时, 外部业务将被挂起, 内务业务完毕时, 外部业务将持续履行。另一方面, PROPAGATION_NESTED 开端一个 "嵌套的" 业务, 它是现已存在业务的一个真实的子业务. 嵌套业务开端履行时, 它将获得一个 savepoint. 假如这个嵌套业务失利, 咱们将回滚到此 savepoint.。嵌套业务是外部业务的一部分, 只要外部业务完毕后它才会被提交。由此可见, PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED 的最大差异在于, PROPAGATION_REQUIRES_NEW 彻底是一个新的业务, 而 PROPAGATION_NESTED 则是外部业务的子业务, 假如外部业务 commit, 潜套业务也会被 commit, 这个规矩相同适用于 roll back.
Java代码 保藏代码
//test1装备PROPAGATION_REQUIRED业务特点
public void test1() throws Exception{
avInfoTaskTunnel.insertAvInfoTask();
otherService.test2(); //PROPAGATION_NESTED业务特点
}

//otherService.test2()
public void test2() throws Exception{
avRequestTunnel.insertAvRequest();
}
上述状况,假如otherService.test2()装备PROPAGATION_REQUIRES_NEW业务特点,这样test1()回滚,可是test2()正常提交,因为这是两个业务。可是假如otherService.test2()装备PROPAGATION_NESTED业务特点,那么test1()和test2()都将回滚。

spring事务声明的几种传播特性

标签:style   http   color   java   os   io   for   ar   art   

原文地址:http://www.cnblogs.com/haomad/p/3934173.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!