-
Spring事务管理未生效5
想用Spring对项目进行数据管理(非web),声明了事务代理,但测试时事务未生效
<!-- 数据库操作类bean --> <bean id="baseService" class="spring.db.impl.BaseServiceImpl"> <property name="dataSource"> <ref bean="dataSource" /> </property> </bean> <!-- 配置JDBC事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource"> <ref bean="dataSource" /> </property> </bean> <!-- 配置事件代理工厂 --> <bean id="transactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <!-- 要依赖事务管理器 --> <property name="transactionManager"> <ref bean="transactionManager" /> </property> <!-- 接口代理方式 --> <property name="proxyInterfaces"> <list> <value>spring.db.Inter.BaseService</value> </list> </property> <!-- 要依赖目标对象 --> <property name="target"> <ref bean="baseService" /> </property> <!-- 要依赖代理方式 --> <!-- <property name="proxyTargetClass" value="true"></property> --> <!-- 要依赖事务属性 --> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED</prop> <prop key="query">PROPAGATION_SUPPORTS,readOnly</prop> <prop key="insert">PROPAGATION_REQUIRED</prop> <prop key="delete">PROPAGATION_REQUIRED</prop> </props> </property> </bean>
package spring.db.impl; import java.sql.Connection; import java.sql.Statement; import javax.sql.DataSource; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceUtils; import spring.db.Inter.BaseService; public class BaseServiceImpl implements BaseService { DataSource dataSource; public DataSource getDataSource() { return dataSource; } public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } /** * 事务声明只读,这应该插入不了数据。测试竟然插进去了 */ @Override public Object query() throws Exception { String sql = "insert into sm_user (ABLE_TIME, AUTHEN_TYPE, CUSERID, DISABLE_TIME, DR, ISCA, KEYUSER, LANGCODE, LOCKED_TAG, PK_CORP, PWDLEVELCODE, PWDPARAM, PWDTYPE, TS, USER_CODE, USER_NAME, USER_NOTE, USER_PASSWORD)" + "values ('2014-05-28', 'staticpwd', 'baidAA10000000000361', '', 0, 'N', '', 'simpchn', 'N', '0001', 'update', '2014-05-28', 0, '2014-05-28 17:51:26', 'a', 'a', '', 'jlehfdffcfmohiag')"; JdbcTemplate jt = new JdbcTemplate(dataSource); jt.execute(sql); return null; } /** * 事务方法抛异常,应该回滚,测试时未进行回滚,数据库保存了一条数据 */ @Override public Integer insert() throws Exception { //通过DataSourceUtils取数据源也不生效 Connection con = DataSourceUtils.getConnection(dataSource); Statement state = con.createStatement(); String sql = "insert into sm_user (ABLE_TIME, AUTHEN_TYPE, CUSERID, DISABLE_TIME, DR, ISCA, KEYUSER, LANGCODE, LOCKED_TAG, PK_CORP, PWDLEVELCODE, PWDPARAM, PWDTYPE, TS, USER_CODE, USER_NAME, USER_NOTE, USER_PASSWORD)" + "values ('2014-05-28', 'staticpwd', 'baiaAA10000000000361', '', 0, 'N', '', 'simpchn', 'N', '0001', 'update', '2014-05-28', 0, '2014-05-28 17:51:26', 'b', 'b', '', 'jlehfdffcfmohiag')"; state.execute(sql); state.execute(sql); DataSourceUtils.doReleaseConnection(con, dataSource); if (true) { throw new Exception("insert 事务测试!"); } return null; } @Override public Integer delete() throws Exception { // Connection con = dataSource.getConnection(); // Statement state = con.createStatement(); String sql = "delete from sm_user where user_code = 'a' or user_code = 'b'"; // state.execute(sql); // if (true) { // throw new Exception("delete 事务测试!"); // } JdbcTemplate jt = new JdbcTemplate(dataSource); jt.execute(sql); return null; } }
package jdbc; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import spring.db.Inter.BaseService; /** * 测试类 * @author tianxingjian * */ public class TransTest { private static ApplicationContext context; private static final String CONFIG_FILE = "bean.xml"; private static BaseService baseService; static { context = new ClassPathXmlApplicationContext(CONFIG_FILE); baseService = (BaseService)context.getBean("baseService"); } @Test public void test() throws Exception{ System.out.println("Start:"); // this.testQuery(); // this.testInsert(); // this.testInsert(); this.testDelete(); System.out.println("End!"); } private void testQuery() throws Exception{ baseService.query(); } private void testInsert() throws Exception{ baseService.insert(); } private void testDelete() throws Exception{ baseService.delete(); } }
2014年5月31日 19:15
2个答案 按时间排序 按投票排序
-
1、你获取的是 context.getBean("baseService"); 而不是他的代理,所以spring无法拦截 管理事务。 应该改为 getBean("transactionProxy")
2、你这种配置 spring 只回滚 运行时异常和错误。 改为throw new RuntimeException("insert 事务测试!"); 就回滚了。
3、 Oracle JDBC driver 不支持 ReadOnly2014年6月03日 17:48
-
“只读事务”并不是一个强制选项,它只是一个“暗示”,提示数据库驱动程序和数据库系统,这个事务并不包含更改数据的操作,那么JDBC驱动程序和数据库就有可能根据这种情况对该事务进行一些特定的优化,比方说不安排相应的数据库锁,以减轻事务对数据库的压力,毕竟事务也是要消耗数据库的资源的。
但是你非要在“只读事务”里面修改数据,也并非不可以,只不过对于数据一致性的保护不像“读写事务”那样保险而已。
因此,“只读事务”仅仅是一个性能优化的推荐配置而已,并非强制你要这样做不可。
比如hibernate的,他知道了这个是只读的,spring就会告知hibernate不要flush(即进行持久化对象和快照比象,不一样的进行更新的)。就是使用了hibernate有可能是不会更新的。2014年6月03日 11:04
相关推荐
标题“Spring事务管理失效原因汇总”指出了本文的核心内容是分析在使用Spring框架进行事务管理时可能遇到的问题及其原因。描述部分进一步说明了事务失效的后果往往不明显,容易在测试环节被忽略,但在生产环境中出现...
Spring事务的回滚规则默认是基于异常的,即只有当方法抛出未捕获的运行时异常时,事务才会回滚。如果捕获了这些异常,事务就不会回滚。例如: ```java @Service public class UserService { @Transactional ...
在Spring框架中,事务管理是核心功能之一,它允许开发者以声明式或编程式的方式处理应用程序的事务。这里我们主要探讨的是"Spring基于XML方式配置事务",这涉及到Spring的事务管理器、事务属性以及如何在XML配置文件...
全面分析 Spring 的编程式事务管理与声明式事务管理 本文将从 Spring 的事务管理入手,深入讲解编程式事务管理和声明式事务管理的实现机制和原理。通过本文的学习,您将能够理解 Spring 事务管理的本质,并灵活运用...
### Spring事务管理详解 在Java应用开发中,事务管理是一个重要的环节,特别是在处理数据库操作时。Spring框架提供了强大的事务管理机制,使得开发者能够方便地控制事务的开启与提交。然而,在实际开发过程中,经常...
在本文中,我们将深入探讨SSH框架中的Spring事务管理流程。SSH(Struts、Hibernate和Spring)是Java Web开发中的经典组合,其中Spring提供了强大的事务管理功能,确保了数据操作的一致性和完整性。下面,我们将详细...
### Spring中的AOP不生效的原因及解决方法 在Java开发中,面向切面编程(Aspect Oriented Programming,简称AOP)是一种重要的编程思想和技术手段,主要用于处理横切关注点问题,如日志记录、性能统计、安全控制、...
内容概要:本文详细讲解了Spring事务管理的核心概念和技术细节。首先介绍了在Spring中启用事务的必要条件和基本步骤,如配置事务管理器并引入相应的依赖。接着,深入探讨了不同类型的事务传播行为,如何通过@...
在Spring框架中,事务管理是...解决这类问题需要从各个角度排查,确保每个环节都符合Spring事务管理的要求。对于具体的代码问题,建议参考官方文档、相关教程和社区讨论,如给出的博客链接,来获取更详细的解答和示例。
- `@Transactional`注解仅在Spring AOP代理能够拦截到的方法上生效,因此,如果在非Spring管理的类或静态方法中使用,事务管理将不起作用。 - 如果事务属性设置不当,可能会导致数据不一致或并发问题,应谨慎调整...
首先,我们要了解Spring事务管理的两个主要模式:编程式事务管理和声明式事务管理。编程式事务管理通常通过PlatformTransactionManager接口实现,例如DataSourceTransactionManager,它需要在代码中显式调用begin、...
Spring项目,数据库用mysql,整合Mybatis,需要自己创建数据库testinnodb,以及两张表Account,int id, int account,表Log,int id ,vchar log。三种事务,手动实现事务,利用AOP实现,以及声明式事务,lib中有所有...
在使用 Spring 和 SpringMVC 配置事务管理时,需要正确配置 Spring 和 SpringMVC 的配置文件,避免重复扫描,确保事务管理生效。本文详细介绍了 Spring+SpringMVC 配置事务管理无效原因及解决办法,希望对大家有所...
最后,启动Spring容器并运行应用,事务管理功能就会生效。 通过这个小实例工程,我们可以学习到如何在Spring 3和Hibernate 4中利用注解实现声明式事务管理,这对于提升代码的可读性和可维护性至关重要。在实际项目...
Spring事务失效的常见场景有七种,分别是:注解@Transactional 配置的方法非 public 权限修饰、注解@Transactional 所在类非 Spring 容器管理的 bean、注解@Transactional 所在类中,注解修饰的方法被类内部方法调用...
spring事务_案例_PPT 一、事务传播机制的demo案例,内容包括: 1.业务代码列举7种事务传播机制的情况,...7.spring事务15种不生效的场景 8.事务的基本属性和常用的属性字段 三、压缩包有数据库和数据表,直接运行即可。
此外,对于非Spring管理的bean,声明式事务可能无法生效。 7. **最佳实践** 在实际项目中,推荐结合使用基于XML和注解的声明式事务管理。对于事务管理的核心逻辑,如事务传播行为和隔离级别,可以在XML配置中统一...
Spring的`<tx:annotation-driven>`标签启用注解驱动的事务管理,使`@Transactional`生效。Struts2的配置文件需要指定Action类及其结果映射,而Mybatis3的配置则包括数据源、SqlSessionFactory和Mapper扫描。 在业务...
为了使声明式事务生效,还需要配置一个`BeanNameAutoProxyCreator`,它会根据指定的bean名称为相应的bean创建事务代理: ```xml <bean id="beanautoproxy" class="org.springframework.aop.framework.autoproxy....
Spring提供了两种事务管理方式:编程式事务管理和声明式事务管理。 ##### 1. 编程式事务管理 编程式事务管理是指通过编写代码来控制事务的开始、提交和回滚。这种方式通常在代码中显式地使用`...