- 浏览: 963900 次
- 性别:
- 来自: 魔都
-
文章分类
- 全部博客 (745)
- MultiThread (19)
- My Plan (118)
- JavaBasic (61)
- MyInterview (104)
- InternetTechnique (5)
- ProjectConclusion (1)
- Maven (5)
- MogoDb (5)
- Hadoop (11)
- Memcached (6)
- TechniqueCollect (1)
- Ibaits (1)
- Android (34)
- ItLife (40)
- Tree (2)
- ProjectArchitect (7)
- Open Source (3)
- liunx (5)
- socket (8)
- Spring (27)
- DesginPattern (35)
- WebBasic (13)
- English (13)
- structs (1)
- structs2 (2)
- Oracle (17)
- Hibernate (2)
- JavaScript (4)
- Jdbc (1)
- Jvm (15)
- Ibatis (1)
- DataStructures (13)
- Https/Socket/Tcp/Ip (3)
- Linux (4)
- Webservice (7)
- Io (2)
- Svn (1)
- Css (1)
- Ajax (1)
- ExtJs (1)
- UML (2)
- DataBase (6)
- BankTechnique (3)
- SpringMvc (3)
- Nio (3)
- Load Balancing/Cluster (3)
- Tools (1)
- javaPerformanceOptimization (8)
- Lucene(SEO) (1)
- My Think (80)
- NodeJs (1)
- Quartz (1)
- Distributed-java (1)
- MySql (7)
- Project (4)
- junit (4)
- framework (1)
- enCache (1)
- git (2)
- SCJP (1)
- sd (1)
最新评论
-
lkjxshi:
你都这水平了还考这个证干嘛
SCJP 认证考试指南 -
钟逸华:
问的真多
百度java开发面试题(转) -
zuimeitulip:
觉得我就是这样的,从小阅读量就很少,导致现在的读的速度非常慢, ...
让读书成为一种习惯 -
DDT_123456:
我觉得你是不符合要求。问你hashmap的那个问题,你那样回答 ...
阿里面试2(转) -
jingjing0907:
刚刚写了很多读过此博客的感受,竟然没有发上去,以为我注册账号还 ...
让读书成为一种习惯
文章链接:http://www.iteye.com/topic/1122176
9.3.5 事务属性
事务属性通过TransactionDefinition接口实现定义,主要有事务隔离级别、事务传播行为、事务超时时间、事务是否只读。
Spring提供TransactionDefinition接口默认实现DefaultTransactionDefinition,可以通过该实现类指定这些事务属性。
事务隔离级别:用来解决并发事务时出现的问题,其使用TransactionDefinition中的静态变量来指定:
ISOLATION_DEFAULT:默认隔离级别,即使用底层数据库默认的隔离级别;
ISOLATION_READ_UNCOMMITTED:未提交读;
ISOLATION_READ_COMMITTED:提交读,一般情况下我们使用这个;
ISOLATION_REPEATABLE_READ:可重复读;
ISOLATION_SERIALIZABLE:序列化。
可以使用DefaultTransactionDefinition类的setIsolationLevel(TransactionDefinition. ISOLATION_READ_COMMITTED)来指定隔离级别,其中此处表示隔离级别为提交读,也可以使用或setIsolationLevelName(“ISOLATION_READ_COMMITTED”)方式指定,其中参数就是隔离级别静态变量的名字,但不推荐这种方式。
事务传播行为:Spring管理的事务是逻辑事务,而且物理事务和逻辑事务最大差别就在于事务传播行为,事务传播行为用于指定在多个事务方法间调用时,事务是如何在这些方法间传播的,Spring共支持7种传播行为:
Required:必须有逻辑事务,否则新建一个事务,使用PROPAGATION_REQUIRED指定,表示如果当前存在一个逻辑事务,则加入该逻辑事务,否则将新建一个逻辑事务,如图9-2和9-3所示;
图9-2 Required传播行为
图9-3 Required传播行为抛出异常情况
在前边示例中就是使用的Required传播行为:
一、在调用userService对象的save方法时,此方法用的是Required传播行为且此时Spring事务管理器发现还没开启逻辑事务,因此Spring管理器觉得开启逻辑事务,
二、在此逻辑事务中调用了addressService对象的save方法,而在save方法中发现同样用的是Required传播行为,因此使用该已经存在的逻辑事务;
三、在返回到addressService对象的save方法,当事务模板类执行完毕,此时提交并关闭事务。
因此userService对象的save方法和addressService的save方法属于同一个物理事务,如果发生回滚,则两者都回滚。
接下来测试一下该传播行为如何执行吧:
一、正确提交测试,如上一节的测试,在此不再演示;
二、回滚测试,修改AddressServiceImpl的save方法片段:
java代码:
Java代码
addressDao.save(address);
为
java代码:
Java代码
addressDao.save(address);
//抛出异常,将标识当前事务需要回滚
throw new RuntimeException();
二、修改UserServiceImpl的save方法片段:
java代码:
Java代码
addressService.save(user.getAddress());
为
java代码:
Java代码
try {
addressService.save(user.getAddress());//将在同一个事务内执行
} catch (RuntimeException e) {
}
如果该业务方法执行时事务被标记为回滚,则不管在此是否捕获该异常都将发生回滚,因为处于同一逻辑事务。
三、修改测试方法片段:
java代码:
Java代码
userService.save(user);
Assert.assertEquals(1, userService.countAll());
Assert.assertEquals(1, addressService.countAll());
为如下形式:
java代码:
Java代码
try {
userService.save(user);
Assert.fail();
} catch (RuntimeException e) {
}
Assert.assertEquals(0, userService.countAll());
Assert.assertEquals(0, addressService.countAll());
Assert断言中countAll方法都返回0,说明事务回滚了,即说明两个业务方法属于同一个物理事务,即使在userService对象的save方法中将异常捕获,由于addressService对象的save方法抛出异常,即事务管理器将自动标识当前事务为需要回滚。
RequiresNew:创建新的逻辑事务,使用PROPAGATION_REQUIRES_NEW指定,表示每次都创建新的逻辑事务(物理事务也是不同的)如图9-4和9-5所示:
图9-4 RequiresNew传播行为
图9-5 RequiresNew传播行为并抛出异常
接下来测试一个该传播行为如何执行吧:
1、将如下获取事务模板方式
java代码:
Java代码
TransactionTemplate transactionTemplate = TransactionTemplateUtils.getDefaultTransactionTemplate(txManager);
替换为如下形式,表示传播行为为RequiresNew:
java代码:
Java代码
TransactionTemplate transactionTemplate = TransactionTemplateUtils.getTransactionTemplate(
txManager,
TransactionDefinition.PROPAGATION_REQUIRES_NEW,
TransactionDefinition.ISOLATION_READ_COMMITTED);
2、执行如下测试,发现执行结果是正确的:
java代码:
Java代码
userService.save(user);
Assert.assertEquals(1, userService.countAll());
Assert.assertEquals(1, addressService.countAll());
3、修改UserServiceImpl的save方法片段
java代码:
Java代码
userDao.save(user);
user.getAddress().setUserId(user.getId());
addressService.save(user.getAddress());
为如下形式,表示userServiceImpl类的save方法将发生回滚,而AddressServiceImpl类的方法由于在抛出异常前执行,将成功提交事务到数据库:
java代码:
Java代码
userDao.save(user);
user.getAddress().setUserId(user.getId());
addressService.save(user.getAddress());
throw new RuntimeException();
4、修改测试方法片段:
java代码:
Java代码
userService.save(user);
Assert.assertEquals(1, userService.countAll());
Assert.assertEquals(1, addressService.countAll());
为如下形式:
java代码:
Java代码
try {
userService.save(user);
Assert.fail();
} catch (RuntimeException e) {
}
Assert.assertEquals(0, userService.countAll());
Assert.assertEquals(1, addressService.countAll());
Assert断言中调用userService对象countAll方法返回0,说明该逻辑事务作用域回滚,而调用addressService对象的countAll方法返回1,说明该逻辑事务作用域正确提交。因此这是不正确的行为,因为用户和地址应该是一一对应的,不应该发生这种情况,因此此处正确的传播行为应该是Required。
该传播行为执行流程(正确提交情况):
一、当执行userService对象的save方法时,由于传播行为是RequiresNew,因此创建一个新的逻辑事务(物理事务也是不同的);
二、当执行到addressService对象的save方法时,由于传播行为是RequiresNew,因此首先暂停上一个逻辑事务并创建一个新的逻辑事务(物理事务也是不同的);
三、addressService对象的save方法执行完毕后,提交逻辑事务(并提交物理事务)并重新恢复上一个逻辑事务,继续执行userService对象的save方法内的操作;
四、最后userService对象的save方法执行完毕,提交逻辑事务(并提交物理事务);
五、userService对象的save方法和addressService对象的save方法不属于同一个逻辑事务且也不属于同一个物理事务。
Supports:支持当前事务,使用PROPAGATION_SUPPORTS指定,指如果当前存在逻辑事务,就加入到该逻辑事务,如果当前没有逻辑事务,就以非事务方式执行,如图9-6和9-7所示:
图9-6 Required+Supports传播行为
图9-7 Supports+Supports传播行为
NotSupported:不支持事务,如果当前存在事务则暂停该事务,使用PROPAGATION_NOT_SUPPORTED指定,即以非事务方式执行,如果当前存在逻辑事务,就把当前事务暂停,以非事务方式执行,如图9-8和9-9所示:
图9-8 Required+NotSupported传播行为
图9-9 Supports+NotSupported传播行为
Mandatory:必须有事务,否则抛出异常,使用PROPAGATION_MANDATORY指定,使用当前事务执行,如果当前没有事务,则抛出异常(IllegalTransactionStateException),如图9-10和9-11所示:
图9-10 Required+Mandatory传播行为
图9-11 Supports+Mandatory传播行为
Never:不支持事务,如果当前存在是事务则抛出异常,使用PROPAGATION_NEVER指定,即以非事务方式执行,如果当前存在事务,则抛出异常(IllegalTransactionStateException),如图9-12和9-13所示:
图9-12 Required+Never传播行为
图9-13 Supports+Never传播行为
Nested:嵌套事务支持,使用PROPAGATION_NESTED指定,如果当前存在事务,则在嵌套事务内执行,如果当前不存在事务,则创建一个新的事务,嵌套事务使用数据库中的保存点来实现,即嵌套事务回滚不影响外部事务,但外部事务回滚将导致嵌套事务回滚,如图9-14和9-15所示:
图9-14 Required+Nested传播行为
图9-15 Nested+Nested传播行为
Nested和RequiresNew的区别:
1、 RequiresNew每次都创建新的独立的物理事务,而Nested只有一个物理事务;
2、 Nested嵌套事务回滚或提交不会导致外部事务回滚或提交,但外部事务回滚将导致嵌套事务回滚,而 RequiresNew由于都是全新的事务,所以之间是无关联的;
3、 Nested使用JDBC 3的保存点实现,即如果使用低版本驱动将导致不支持嵌套事务。
使用嵌套事务,必须确保具体事务管理器实现的nestedTransactionAllowed属性为true,否则不支持嵌套事务,如DataSourceTransactionManager默认支持,而HibernateTransactionManager默认不支持,需要我们来开启。
对于事务传播行为我们只演示了Required和RequiresNew,其他传播行为类似,如果对这些事务传播行为不太会使用,请参考chapter9包下的TransactionTest测试类中的testPropagation方法,方法内有详细示例。
事务超时:设置事务的超时时间,单位为秒,默认为-1表示使用底层事务的超时时间;
使用如setTimeout(100)来设置超时时间,如果事务超时将抛出org.springframework.transaction.TransactionTimedOutException异常并将当前事务标记为应该回滚,即超时后事务被自动回滚;
可以使用具体事务管理器实现的defaultTimeout属性设置默认的事务超时时间,如DataSourceTransactionManager. setDefaultTimeout(10)。
事务只读:将事务标识为只读,只读事务不修改任何数据;
对于JDBC只是简单的将连接设置为只读模式,对于更新将抛出异常;
而对于一些其他ORM框架有一些优化作用,如在Hibernate中,Spring事务管理器将执行“session.setFlushMode(FlushMode.MANUAL)”即指定Hibernate会话在只读事务模式下不用尝试检测和同步持久对象的状态的更新。
如果使用设置具体事务管理的validateExistingTransaction属性为true(默认false),将确保整个事务传播链都是只读或都不是只读,如图9-16是正确的事务只读设置,而图9-17是错误的事务只读设置:
图9-16 正确的事务只读设置
图9-17 错误的事务只读设置
如图10-17,对于错误的事务只读设置将抛出IllegalTransactionStateException异常,并伴随“Participating transaction with definition [……] is not marked as read-only……”信息,表示参与的事务只读属性设置错误。
详见博客
【第九章】 Spring的事务 之 9.3 编程式事务 ——跟我学spring3
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
想进外企,出国,跳槽,找工作?英语不好,快来充电吧
100万现金奖培训出来的程序员
返回顶楼
jinnianshilongnian
等级:
文章: 226
积分: 700
发表时间:10 小时前 最后修改:9 小时前 引用 收藏
代理方式下的自我调用
图9-18 代理方式实现事务管理
如图9-18,代理方式实现事务管理只是将硬编码的事务管理代码转移到代理中去由代理实现,在代理中实现事务管理。
注:在代理模式下,默认只有通过代理对象调用的方法才能应用相应的事务属性,而在目标方法内的“自我调用”是不会应用相应的事务属性的,即被调用方法不会应用相应的事务属性,而是使用调用方法的事务属性。
如图9-19所示,在目标对象targetUserService的save方法内调用事务方法“this.otherTransactionMethod()”将不会应用配置的传播行为RequriesNew,开启新事务,而是使用save方法的已开启事务,如果非要这样使用如下方式实现:
1、 修改TransactionProxyFactoryBean配置定义,添加exposeProxy属性为true;
2、 在业务方法内通过代理对象调用相应的事务方放,如 “((IUserService)AopContext.currentProxy()).otherTransactionMethod()”即可应用配置的事务属性。
3、 使用这种方式属于侵入式,不推荐使用,除非必要。
图9-19 代理方式下的自我调用
9.3.5 事务属性
事务属性通过TransactionDefinition接口实现定义,主要有事务隔离级别、事务传播行为、事务超时时间、事务是否只读。
Spring提供TransactionDefinition接口默认实现DefaultTransactionDefinition,可以通过该实现类指定这些事务属性。
事务隔离级别:用来解决并发事务时出现的问题,其使用TransactionDefinition中的静态变量来指定:
ISOLATION_DEFAULT:默认隔离级别,即使用底层数据库默认的隔离级别;
ISOLATION_READ_UNCOMMITTED:未提交读;
ISOLATION_READ_COMMITTED:提交读,一般情况下我们使用这个;
ISOLATION_REPEATABLE_READ:可重复读;
ISOLATION_SERIALIZABLE:序列化。
可以使用DefaultTransactionDefinition类的setIsolationLevel(TransactionDefinition. ISOLATION_READ_COMMITTED)来指定隔离级别,其中此处表示隔离级别为提交读,也可以使用或setIsolationLevelName(“ISOLATION_READ_COMMITTED”)方式指定,其中参数就是隔离级别静态变量的名字,但不推荐这种方式。
事务传播行为:Spring管理的事务是逻辑事务,而且物理事务和逻辑事务最大差别就在于事务传播行为,事务传播行为用于指定在多个事务方法间调用时,事务是如何在这些方法间传播的,Spring共支持7种传播行为:
Required:必须有逻辑事务,否则新建一个事务,使用PROPAGATION_REQUIRED指定,表示如果当前存在一个逻辑事务,则加入该逻辑事务,否则将新建一个逻辑事务,如图9-2和9-3所示;
图9-2 Required传播行为
图9-3 Required传播行为抛出异常情况
在前边示例中就是使用的Required传播行为:
一、在调用userService对象的save方法时,此方法用的是Required传播行为且此时Spring事务管理器发现还没开启逻辑事务,因此Spring管理器觉得开启逻辑事务,
二、在此逻辑事务中调用了addressService对象的save方法,而在save方法中发现同样用的是Required传播行为,因此使用该已经存在的逻辑事务;
三、在返回到addressService对象的save方法,当事务模板类执行完毕,此时提交并关闭事务。
因此userService对象的save方法和addressService的save方法属于同一个物理事务,如果发生回滚,则两者都回滚。
接下来测试一下该传播行为如何执行吧:
一、正确提交测试,如上一节的测试,在此不再演示;
二、回滚测试,修改AddressServiceImpl的save方法片段:
java代码:
Java代码
addressDao.save(address);
为
java代码:
Java代码
addressDao.save(address);
//抛出异常,将标识当前事务需要回滚
throw new RuntimeException();
二、修改UserServiceImpl的save方法片段:
java代码:
Java代码
addressService.save(user.getAddress());
为
java代码:
Java代码
try {
addressService.save(user.getAddress());//将在同一个事务内执行
} catch (RuntimeException e) {
}
如果该业务方法执行时事务被标记为回滚,则不管在此是否捕获该异常都将发生回滚,因为处于同一逻辑事务。
三、修改测试方法片段:
java代码:
Java代码
userService.save(user);
Assert.assertEquals(1, userService.countAll());
Assert.assertEquals(1, addressService.countAll());
为如下形式:
java代码:
Java代码
try {
userService.save(user);
Assert.fail();
} catch (RuntimeException e) {
}
Assert.assertEquals(0, userService.countAll());
Assert.assertEquals(0, addressService.countAll());
Assert断言中countAll方法都返回0,说明事务回滚了,即说明两个业务方法属于同一个物理事务,即使在userService对象的save方法中将异常捕获,由于addressService对象的save方法抛出异常,即事务管理器将自动标识当前事务为需要回滚。
RequiresNew:创建新的逻辑事务,使用PROPAGATION_REQUIRES_NEW指定,表示每次都创建新的逻辑事务(物理事务也是不同的)如图9-4和9-5所示:
图9-4 RequiresNew传播行为
图9-5 RequiresNew传播行为并抛出异常
接下来测试一个该传播行为如何执行吧:
1、将如下获取事务模板方式
java代码:
Java代码
TransactionTemplate transactionTemplate = TransactionTemplateUtils.getDefaultTransactionTemplate(txManager);
替换为如下形式,表示传播行为为RequiresNew:
java代码:
Java代码
TransactionTemplate transactionTemplate = TransactionTemplateUtils.getTransactionTemplate(
txManager,
TransactionDefinition.PROPAGATION_REQUIRES_NEW,
TransactionDefinition.ISOLATION_READ_COMMITTED);
2、执行如下测试,发现执行结果是正确的:
java代码:
Java代码
userService.save(user);
Assert.assertEquals(1, userService.countAll());
Assert.assertEquals(1, addressService.countAll());
3、修改UserServiceImpl的save方法片段
java代码:
Java代码
userDao.save(user);
user.getAddress().setUserId(user.getId());
addressService.save(user.getAddress());
为如下形式,表示userServiceImpl类的save方法将发生回滚,而AddressServiceImpl类的方法由于在抛出异常前执行,将成功提交事务到数据库:
java代码:
Java代码
userDao.save(user);
user.getAddress().setUserId(user.getId());
addressService.save(user.getAddress());
throw new RuntimeException();
4、修改测试方法片段:
java代码:
Java代码
userService.save(user);
Assert.assertEquals(1, userService.countAll());
Assert.assertEquals(1, addressService.countAll());
为如下形式:
java代码:
Java代码
try {
userService.save(user);
Assert.fail();
} catch (RuntimeException e) {
}
Assert.assertEquals(0, userService.countAll());
Assert.assertEquals(1, addressService.countAll());
Assert断言中调用userService对象countAll方法返回0,说明该逻辑事务作用域回滚,而调用addressService对象的countAll方法返回1,说明该逻辑事务作用域正确提交。因此这是不正确的行为,因为用户和地址应该是一一对应的,不应该发生这种情况,因此此处正确的传播行为应该是Required。
该传播行为执行流程(正确提交情况):
一、当执行userService对象的save方法时,由于传播行为是RequiresNew,因此创建一个新的逻辑事务(物理事务也是不同的);
二、当执行到addressService对象的save方法时,由于传播行为是RequiresNew,因此首先暂停上一个逻辑事务并创建一个新的逻辑事务(物理事务也是不同的);
三、addressService对象的save方法执行完毕后,提交逻辑事务(并提交物理事务)并重新恢复上一个逻辑事务,继续执行userService对象的save方法内的操作;
四、最后userService对象的save方法执行完毕,提交逻辑事务(并提交物理事务);
五、userService对象的save方法和addressService对象的save方法不属于同一个逻辑事务且也不属于同一个物理事务。
Supports:支持当前事务,使用PROPAGATION_SUPPORTS指定,指如果当前存在逻辑事务,就加入到该逻辑事务,如果当前没有逻辑事务,就以非事务方式执行,如图9-6和9-7所示:
图9-6 Required+Supports传播行为
图9-7 Supports+Supports传播行为
NotSupported:不支持事务,如果当前存在事务则暂停该事务,使用PROPAGATION_NOT_SUPPORTED指定,即以非事务方式执行,如果当前存在逻辑事务,就把当前事务暂停,以非事务方式执行,如图9-8和9-9所示:
图9-8 Required+NotSupported传播行为
图9-9 Supports+NotSupported传播行为
Mandatory:必须有事务,否则抛出异常,使用PROPAGATION_MANDATORY指定,使用当前事务执行,如果当前没有事务,则抛出异常(IllegalTransactionStateException),如图9-10和9-11所示:
图9-10 Required+Mandatory传播行为
图9-11 Supports+Mandatory传播行为
Never:不支持事务,如果当前存在是事务则抛出异常,使用PROPAGATION_NEVER指定,即以非事务方式执行,如果当前存在事务,则抛出异常(IllegalTransactionStateException),如图9-12和9-13所示:
图9-12 Required+Never传播行为
图9-13 Supports+Never传播行为
Nested:嵌套事务支持,使用PROPAGATION_NESTED指定,如果当前存在事务,则在嵌套事务内执行,如果当前不存在事务,则创建一个新的事务,嵌套事务使用数据库中的保存点来实现,即嵌套事务回滚不影响外部事务,但外部事务回滚将导致嵌套事务回滚,如图9-14和9-15所示:
图9-14 Required+Nested传播行为
图9-15 Nested+Nested传播行为
Nested和RequiresNew的区别:
1、 RequiresNew每次都创建新的独立的物理事务,而Nested只有一个物理事务;
2、 Nested嵌套事务回滚或提交不会导致外部事务回滚或提交,但外部事务回滚将导致嵌套事务回滚,而 RequiresNew由于都是全新的事务,所以之间是无关联的;
3、 Nested使用JDBC 3的保存点实现,即如果使用低版本驱动将导致不支持嵌套事务。
使用嵌套事务,必须确保具体事务管理器实现的nestedTransactionAllowed属性为true,否则不支持嵌套事务,如DataSourceTransactionManager默认支持,而HibernateTransactionManager默认不支持,需要我们来开启。
对于事务传播行为我们只演示了Required和RequiresNew,其他传播行为类似,如果对这些事务传播行为不太会使用,请参考chapter9包下的TransactionTest测试类中的testPropagation方法,方法内有详细示例。
事务超时:设置事务的超时时间,单位为秒,默认为-1表示使用底层事务的超时时间;
使用如setTimeout(100)来设置超时时间,如果事务超时将抛出org.springframework.transaction.TransactionTimedOutException异常并将当前事务标记为应该回滚,即超时后事务被自动回滚;
可以使用具体事务管理器实现的defaultTimeout属性设置默认的事务超时时间,如DataSourceTransactionManager. setDefaultTimeout(10)。
事务只读:将事务标识为只读,只读事务不修改任何数据;
对于JDBC只是简单的将连接设置为只读模式,对于更新将抛出异常;
而对于一些其他ORM框架有一些优化作用,如在Hibernate中,Spring事务管理器将执行“session.setFlushMode(FlushMode.MANUAL)”即指定Hibernate会话在只读事务模式下不用尝试检测和同步持久对象的状态的更新。
如果使用设置具体事务管理的validateExistingTransaction属性为true(默认false),将确保整个事务传播链都是只读或都不是只读,如图9-16是正确的事务只读设置,而图9-17是错误的事务只读设置:
图9-16 正确的事务只读设置
图9-17 错误的事务只读设置
如图10-17,对于错误的事务只读设置将抛出IllegalTransactionStateException异常,并伴随“Participating transaction with definition [……] is not marked as read-only……”信息,表示参与的事务只读属性设置错误。
详见博客
【第九章】 Spring的事务 之 9.3 编程式事务 ——跟我学spring3
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
想进外企,出国,跳槽,找工作?英语不好,快来充电吧
100万现金奖培训出来的程序员
返回顶楼
jinnianshilongnian
等级:
文章: 226
积分: 700
发表时间:10 小时前 最后修改:9 小时前 引用 收藏
代理方式下的自我调用
图9-18 代理方式实现事务管理
如图9-18,代理方式实现事务管理只是将硬编码的事务管理代码转移到代理中去由代理实现,在代理中实现事务管理。
注:在代理模式下,默认只有通过代理对象调用的方法才能应用相应的事务属性,而在目标方法内的“自我调用”是不会应用相应的事务属性的,即被调用方法不会应用相应的事务属性,而是使用调用方法的事务属性。
如图9-19所示,在目标对象targetUserService的save方法内调用事务方法“this.otherTransactionMethod()”将不会应用配置的传播行为RequriesNew,开启新事务,而是使用save方法的已开启事务,如果非要这样使用如下方式实现:
1、 修改TransactionProxyFactoryBean配置定义,添加exposeProxy属性为true;
2、 在业务方法内通过代理对象调用相应的事务方放,如 “((IUserService)AopContext.currentProxy()).otherTransactionMethod()”即可应用配置的事务属性。
3、 使用这种方式属于侵入式,不推荐使用,除非必要。
图9-19 代理方式下的自我调用
发表评论
-
spring原理
2013-07-31 23:21 8881、spring原理 s ... -
通过实例浅谈Spring运作机制
2013-07-31 23:06 1177看到这个标题大家可能又想:哎,又一个重新发明轮子的人。在这里 ... -
spring用到的设计模式
2013-06-24 21:45 1207spring源码也读了两遍了,但对于里面描述的关系还是不太 ... -
SPRING事务的属性有哪些?其中,事务隔离级别有哪几种?什么情况需要使用这几种事务隔离级别?
2013-04-14 20:45 3867Spring 声明式事务,propagation属性列表 PR ... -
Spring定时任务的几种实现
2013-01-24 10:32 1021Spring定时任务的几种实现 近日项目开发中需要执行一些 ... -
Spring多数据源解决方案
2012-10-02 22:49 1103... -
spring是如何管理 事务的
2012-07-08 14:43 1535Spring提供的事务管理可以分为两类:编程式的和声明式的。 ... -
【第六章】 AOP 之 6.9 代理机制 ——跟我学spring3
2012-07-07 12:36 880Spring AOP通过代理模式实现,目前支持两 ... -
【第九章】 Spring的事务 之 9.1 数据库事务概述 ——跟我学spring3
2012-07-07 12:37 10029.1 数据库事务概述 事 ... -
【第九章】 Spring的事务 之 9.2 事务管理器 ——跟我学spring3
2012-07-07 12:37 10209.2.1 概述 ... -
【第九章】 Spring的事务 之 9.3 编程式事务 ——跟我学spring3
2012-07-06 00:03 9219.3 编程式事务 9.3.1 编程式事务 ... -
【第九章】 Spring的事务 之 9.4 声明式事务 ——跟我学spring3
2012-07-06 00:03 7639.4 声明式事务 9.4.1 声明式事务 ... -
我对AOP的理解
2012-07-06 00:02 8941、问题 问题:想要添加日志记录 ... -
我对IoC/DI的理解
2012-07-06 00:01 1032IoC IoC: Inversion of ... -
基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别。
2012-07-06 00:02 2369基于JDK动态代理和CGLIB动态代理的实现S ... -
Spring对事务管理的支持的发展历程(基础篇)
2012-07-05 23:00 9891、问题 Java代 ... -
阅读spring源码
2012-07-05 21:22 1734读Spring源码之前,你要先清楚,为什么你要用S ... -
spring aop 详解
2012-07-01 18:41 1191文章链接:http://stamen.itey ... -
Spring ioc 详解
2012-07-01 18:14 2060文章链接:http://stamen.itey ... -
spring事务探索
2012-07-01 16:46 1014文章链接:http://www.iteye.com/topic ...
相关推荐
### Spring事务模板及afterCommit存在的坑 #### 一、为何避免使用`@Transactional`注解? 在支付系统设计中,通常会优先选择使用事务模板方法而非`@Transactional`注解来处理事务。这一做法主要是出于对事务粒度的...
此外,通过`<tx:advice>`和`<tx:attributes>`标签,可以配置Spring的AOP事务管理策略,比如定义哪些方法需要事务处理,以及它们的事务传播行为。 3. **Struts2** 是一个MVC框架,用于处理前端请求和控制业务逻辑。...
这表示所有方法都采用默认的 `REQUIRED` 事务传播属性。 ### 3. 事务处理 Spring 的事务管理是基于 AOP 的,这意味着事务处理可以在方法调用的周围自动插入。在上述配置中,我们已经设置了所有方法都要求在事务内...
6. **事务管理**:Spring提供了编程式和声明式的事务管理,可以方便地处理跨层的事务问题。 7. **Spring Boot**:Spring Boot是近年来流行的快速开发工具,它简化了Spring应用的初始化和配置,提供了自动配置和...
2. **配置事务切面**: 使用 AOP 配置事务切面,指定事务的传播行为和隔离级别。 #### 十二、配置OpenSessionInView过滤器 1. **配置 OpenSessionInView**: 在 web.xml 中配置 OpenSessionInView 过滤器,确保在一...
Context组件是Spring的核心,它构建在Core之上,提供了一个更丰富的上下文环境,能够管理Bean的生命周期,处理Bean之间的依赖关系,并且支持国际化、事件传播等功能。Context通常被视为应用上下文,它可以是...