spring 注解事务控制 简单问题

不戒的信仰 2010-11-14 05:53:43
用的是spring的JdbcTemplate操作,配置了注解事务控制,但不起作用,代码如下:

配置文件 applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">


<context:property-placeholder location="framconfig.properties" />
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">

<property name="driverClassName" value="${driverClassName}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
<!-- dbcp 连接池启动时的初始值 -->
<property name="initialSize" value="${initialSize}" />
<!-- 连接池的最大值 -->
<property name="maxActive" value="${maxActive}" />
<!-- 最大空闲值,当一个高峰期时间过后,连接池可以慢慢将已经用不到的连接池释放一部分 ,一直减少到maxIdle为止 -->
<property name="maxIdle" value="${maxIdle}" />
<!-- 最小空闲值,当空闲的连接数量少去阀值时,连接池就会预申请一些链接,以免洪峰来时来不及申请 -->
<property name="minIdle" value="${minIdle}" />
</bean>

<!--JDBC事务管理器,根据 情况使用不同的事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>

<!-- 用注解来实现事务管理 -->
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="DBHelperInf"
class="net.jtribe.famework.frame.core.jdbc.DBHelper">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>


文件framconfig.properties

driverClassName=oracle.jdbc.driver.OracleDriver
url=jdbc\:oracle\:thin\:@127.0.0.1\:1521\:ORCL
username=smanager
password=smanager
initialSize=1
maxActive=500
maxIdle=2
minIdle=1

DBHelper.java

package net.jtribe.famework.frame.core.jdbc;

import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;
import net.jtribe.famework.frame.core.jdbc.DBHelperInf;

/**
* @author
*
*/

@Transactional
public class DBHelper implements DBHelperInf {

public JdbcTemplate jdbcTemplate;

@Resource
public void setDataSource(DataSource dataSource) {

this.jdbcTemplate = new JdbcTemplate(dataSource);// 把数据源传进去
}

public List query(String sql, Object[] values, int[] type) {
return jdbcTemplate.queryForList(sql, values, type);

}

public List query(String sql) {
return jdbcTemplate.queryForList(sql);
}

public Map queryForMap(String sql) {
return jdbcTemplate.queryForMap(sql);
}

public List query(String sql, int pageSize, int pageIndex) {
// TODO Auto-generated method stub
return null;
}

public List query(String preparedSql, String[] args, int[] argTypes,
int pageSize, int pageIndex) {
// TODO Auto-generated method stub
return null;
}

public List queryForBinaryStream(String sql, OutputStream os) {
// TODO Auto-generated method stub
return null;
}

public List queryForBinaryStream(String preparedSql, String[] args,
int[] argTypes, OutputStream os) {
// TODO Auto-generated method stub
return null;
}

public Map queryForMap(String sql, Object[] args, int[] argTypes) {
// TODO Auto-generated method stub
return null;
}

public int update(String sql) {
// TODO Auto-generated method stub
return 0;
}

public int update(String sql, Object[] args, int[] argTypes) {
return jdbcTemplate.update(sql, args, argTypes);

}

}


DBHelperInf.java

package net.jtribe.famework.frame.core.jdbc;

import java.util.List;
import java.util.Map;

public interface DBHelperInf {
public List query(String sql, Object[] values, int[] type);

public List query(String sql);

public Map queryForMap(String sql);

public Map queryForMap(String sql, Object[] args, int[] argTypes);

public int update(String sql);

public int update(String sql, Object[] args, int[] argTypes);

public List queryForBinaryStream(java.lang.String sql,
java.io.OutputStream os);

public List queryForBinaryStream(java.lang.String preparedSql,
java.lang.String[] args, int[] argTypes, java.io.OutputStream os);

public List query(String sql, int pageSize, int pageIndex);

public List query(String preparedSql, java.lang.String[] args,
int[] argTypes, int pageSize, int pageIndex);

}


BaseAction.java

package net.jtribe.famework.frame.biz;


import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.transaction.annotation.Transactional;
import net.jtribe.famework.frame.core.jdbc.DBHelperInf;

@Transactional
public class BaseAction {

/**
* 数据库专家类,获得数据资源.
*/

public static DBHelperInf getUpBeforeClass() {
DBHelperInf dbHelperInf = null;
try {
ApplicationContext tx = new ClassPathXmlApplicationContext("transactionconfig.xml");
dbHelperInf = (DBHelperInf) tx.getBean("DBHelperInf");
throw new RuntimeException("运行期例外");


} catch (Exception e) {
e.printStackTrace();
}

return dbHelperInf;

}

public static DBHelperInf dbHelperInf = BaseAction.getUpBeforeClass();
public static Logger log = Logger.getLogger(BaseAction.class);


}



测试方法TestSpring.java


package net.test;

import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import net.jtribe.famework.frame.biz.BaseAction;
import java.sql.Types;
import java.util.List;

@Transactional
public class TestSpring extends BaseAction {
/**
* 数据库专家类,获得数据资源.
*/

@Transactional(isolation = Isolation.READ_COMMITTED)
public void process( ) {
dbHelperInf.update("insert into test1 ( id,sj,nr )values(?,?,?)", new Object[]{1,"134522222","王强"}, new int[]{Types.NUMERIC,Types.VARCHAR,Types.VARCHAR});//记录一
dbHelperInf.update("insert into test12 ( id,sj,nr )values(?,?,?)", new Object[]{1,"134522222","王强"}, new int[]{Types.NUMERIC,Types.VARCHAR,Types.VARCHAR});//表test12 不存在,

throw new RuntimeException("运行期例外");
}

public static void main(String[] args) {
TestSpring TestSpring = new TestSpring();
TestSpring.process( );
}

}

表test12 不存在,事务应该回滚才对的,可最终结果是没有回滚,记录一
成功插入了,怎么回事呢???
...全文
423 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
zn85600301 2010-11-15
  • 打赏
  • 举报
回复
1,2楼说的都对
楼主最好还是用junit写测试类 或者跑起来测试
还有你的事务配到了dbHelperInf 所以每个dbHelperInf 的方法是独立的事务
要么你配置到Manager层 要么你自己开启事务控制
sound9world 2010-11-14
  • 打赏
  • 举报
回复
update()被事务管理了,但调用两个update()的process()方法并没有进行事务管理

也就是process()有种两个事务存在 第二个回滚了 第一个操作成功
howsun_zh 2010-11-14
  • 打赏
  • 举报
回复
TestSpring的process方法没在事务之内。
楼主贴出的三个类(那个接口除外),只有DBHelper在事务管理之内。因为BaseAction才开始启动容器,很显然连BaseAction和TestSpring两个类都不在Spring容器中,怎么能有事务呢(或者说@Transactional
注解谁能解读呢)?

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧