Spring 声明式事务@Transactional不起作用,为什么

doublecake 2015-04-10 02:43:46
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

<tx:annotation-driven transaction-manager="txManager" />
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${c3p0.driverClass}"></property>
<property name="jdbcUrl" value="${c3p0.url}"></property>
<property name="user" value="${c3p0.user}"></property>
<property name="password" value="${c3p0.password}"></property>
<property name="acquireIncrement" value="${c3p0.acquireIncrement}"></property>
<property name="initialPoolSize" value="${c3p0.initialPoolSize}"></property>
<property name="maxIdleTime" value="${c3p0.maxIdleTime}"></property>
<property name="maxPoolSize" value="${c3p0.maxPoolSize}"></property>
<property name="minPoolSize" value="${c3p0.minPoolSize}"></property>

<property name="acquireRetryDelay" value="1000"></property>
<property name="acquireRetryAttempts" value="60"></property>
<property name="breakAfterAcquireFailure" value="false"></property>
</bean>

<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath*:c3p0.properties</value>
</list>
</property>
</bean>

<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>



求大神帮助
...全文
4048 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
虾米吃小鱼 2015-12-08
  • 打赏
  • 举报
回复
知道问题这个朋友找到答案了么,我也是碰到这个问题哇
guoweiqaz 2015-04-18
  • 打赏
  • 举报
回复
你在dao中用datasource获取连接,spring事物是不支持的
guoweiqaz 2015-04-18
  • 打赏
  • 举报
回复
dao自己写这么多关于connection的代码干什么,spring不是有jdbctemplete么
风程序 2015-04-15
  • 打赏
  • 举报
回复
http://blog.csdn.net/w215230188/article/details/44967039 看下这边文章 希望能帮到你
Inhibitory 2015-04-14
  • 打赏
  • 举报
回复
引用 18 楼 doublecake 的回复:
[quote=引用 17 楼 Inhibitory 的回复:] 事务的配置是在哪个 context 里配置的? Spring里父context看不到子context的内容,父context配置的事务在子context不会生效。
@Inhibitory 我配置了三个两个spring 的文件第一个spring-context.xml就是上面的,第二个是spring-mvc.xml,主要配置的是mvc的相关的信息,这个有什么问题吗??[/quote] Transaction在 spring-mvc.xml里配置试试,可以看看我的这个配置 http://qtdebug.com/java/14.%20Spring%20%E4%BA%8B%E5%8A%A1%E5%A4%84%E7%90%86.html
doublecake 2015-04-14
  • 打赏
  • 举报
回复
引用 17 楼 Inhibitory 的回复:
事务的配置是在哪个 context 里配置的? Spring里父context看不到子context的内容,父context配置的事务在子context不会生效。
@Inhibitory 我配置了三个两个spring 的文件第一个spring-context.xml就是上面的,第二个是spring-mvc.xml,主要配置的是mvc的相关的信息,这个有什么问题吗??
Inhibitory 2015-04-13
  • 打赏
  • 举报
回复
事务的配置是在哪个 context 里配置的? Spring里父context看不到子context的内容,父context配置的事务在子context不会生效。
doublecake 2015-04-13
  • 打赏
  • 举报
回复


package cn.com.silence310.dao;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PreDestroy;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.mchange.v2.c3p0.ComboPooledDataSource;

/**
 * 数据库基类
 * 
 * @author XMX 建议:
 *
 */
@Component
public class BaseDao {
	@Autowired
	public ComboPooledDataSource ds = null;

	private Connection connection = null;

	private Statement statement = null;

	// 关闭相关链接和rs
	/**
	 * 没用完之前不要关。。。 建议外部使用
	 * 
	 * @param rs
	 * @throws SQLException
	 */
	public void free(ResultSet rs) throws SQLException {
		close(rs, this.statement, this.connection);
	}

	/**
	 * 执行操作前,初始化当前statement和链接
	 * 
	 * @throws SQLException
	 */
	private void init() throws SQLException {
		if (this.connection == null || this.connection.isClosed()) {
			this.connection = this.ds.getConnection();
			this.statement = this.connection.createStatement();
		} else {
			this.statement = this.connection.createStatement();
		}
	}

	public void close(ResultSet rs, Statement st, Connection conn) {

		try {

			if (rs != null)

				rs.close();

		} catch (SQLException e) {

			System.out.println("未成功关闭ResultSet");

			e.printStackTrace();

		} finally {

			try {

				if (st != null)

					st.close();

			} catch (SQLException e) {

				System.out.println("未成功关闭Statement");

				e.printStackTrace();

			} finally {

				if (conn != null)

					try {

						conn.close();

					} catch (SQLException e) {

						System.out.println("未成功关闭Connection");

						e.printStackTrace();

					}

			}

		}

	}

	public void close(Statement st, Connection conn) {

		try {

			if (st != null)

				st.close();

		} catch (SQLException e) {

			System.out.println("未成功关闭Statement");

			e.printStackTrace();

		} finally {

			if (conn != null)

				try {

					conn.close();

				} catch (SQLException e) {

					e.printStackTrace();

				}

		}

	}

	// 直接把链接返回连接池,并不是关闭链接
	public void close(Connection conn) {

		if (conn != null)

			try {

				conn.close();

			} catch (SQLException e) {

				System.out.println("未成功关闭Connection");

				e.printStackTrace();
			}

	}

	// Dao被销毁前执行操作,关闭statment,并返回链接到连接池
	@PreDestroy
	void destory() {
		close(this.statement, this.connection);
		System.err.println("链接返回连接池");
	}

	public ResultSet executeQuery(String sql) throws SQLException {
		init();
		ResultSet rs = null;
		try {
			rs = this.statement.executeQuery(sql);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return rs;
	}

	public int executeUpdate(String sql) throws SQLException {
		init();
		int count = 0;
		try {
			count = this.statement.executeUpdate(sql);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return count;
	}

	public JSONArray queryJSON(String sql) throws SQLException {
		init();
		ResultSet rs = null;
		JSONArray rsJsonArray = new JSONArray();
		try {
			rs = this.statement.executeQuery(sql);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		ResultSetMetaData metaData = rs.getMetaData();
		int cloumnCount = metaData.getColumnCount();
		while (rs.next()) {
			JSONObject cloumn = new JSONObject();
			for (int i = 0; i < cloumnCount; i++) {
				String columnName = metaData.getColumnLabel(i);
				String value = rs.getString(columnName);
				try {
					cloumn.put(columnName, value);
					rsJsonArray.put(cloumn);
				} catch (JSONException e) {
					e.printStackTrace();
				}
			}
		}
		return rsJsonArray;
	}

	public void free() {
		close(this.statement, this.connection);
	}

	/**
	 * rs转List<Map>
	 * 
	 * @param rs
	 * @return
	 * @throws SQLException
	 */
	private List ResultToListMap(ResultSet rs) throws SQLException {
		List list = new ArrayList();
		while (rs.next()) {
			ResultSetMetaData md = rs.getMetaData();
			Map map = new HashMap();
			for (int i = 1; i < md.getColumnCount(); i++) {
				map.put(md.getColumnLabel(i), rs.getObject(i));
			}
			list.add(map);
		}
		return list;
	}

	/**
	 * @author XMX
	 * @param sql
	 * @return
	 * @throws SQLException
	 */
	public List query(String sql) throws SQLException {
		init();
		ResultSet rs = null;
		PreparedStatement preparedStatement = null;
		try {
			preparedStatement = this.connection.prepareStatement(sql);
			rs = preparedStatement.executeQuery();
			return ResultToListMap(rs);
		} catch (SQLException e) {
			throw new SQLException(e);
		} finally {
			free(rs);
			preparedStatement.close();
		}

	}

	/**
	 * 用于带参数的查询,返回结果集
	 * @author XMX
	 * @param sql
	 * @param paramters 参数集合
	 * @return 结果集
	 * @throws SQLException
	 */
	@SuppressWarnings("rawtypes")
	public List query(String sql, Object... paramters)
			throws SQLException {
		init();
		ResultSet rs = null;
		PreparedStatement preparedStatement = null;
		try {
			preparedStatement = this.connection.prepareStatement(sql);
			for (int i = 0; i < paramters.length; i++) {
				preparedStatement.setObject(i + 1, paramters[i]);
			}
			rs = preparedStatement.executeQuery();
			return ResultToListMap(rs);
		} catch (SQLException e) {
			throw new SQLException(e);
		} finally {
			free(rs);
			preparedStatement.close();
		}
	}
	 /**
     * 返回单个结果的值,如count\min\max等等
     * @author XMX
     * @param sql语句
     *            
     * @return 结果集
     * @throws SQLException
     */
	public Object getSingle(String sql) throws SQLException {
		init();
        Object result = null;
        ResultSet rs = null;
		PreparedStatement preparedStatement = null;
        try {
        	preparedStatement = this.connection.prepareStatement(sql);
            rs = preparedStatement.executeQuery();
            if (rs.next()) {
                result = rs.getObject(1);
            }
            return result;
        } catch (SQLException e) {
            throw new SQLException(e);
        } finally {
            free(rs);
            preparedStatement.close();
        }
    }
	/**
	 * @author XMX
	 * @param sql
	 * @param paramters
	 * @return
	 * @throws SQLException
	 */
	public  Object getSingle(String sql, Object... paramters)
            throws SQLException {
		init();
        Object result = null;
        ResultSet rs = null;
		PreparedStatement preparedStatement = null;
        try {
        	preparedStatement = this.connection.prepareStatement(sql);
 
            for (int i = 0; i < paramters.length; i++) {
                preparedStatement.setObject(i + 1, paramters[i]);
            }
            rs = preparedStatement.executeQuery();
            if (rs.next()) {
                result = rs.getObject(1);
            }
            return result;
        } catch (SQLException e) {
            throw new SQLException(e);
        } finally {
            free(rs);
            preparedStatement.close();
        }
    }
	
	
	
	
	 /**
     * 用于增删改
     * 
     * @param sql
     *            sql语句
     * @return 影响行数
     * @throws SQLException
     */
    public  int update(String sql) throws SQLException {
    	init();
		PreparedStatement preparedStatement = null;
        try {
        	preparedStatement = this.connection.prepareStatement(sql);
            return preparedStatement.executeUpdate();
        } catch (SQLException e) {
            throw new SQLException(e);
        } finally {
            free();
            preparedStatement.close();
        }
    }
 
    /**
     * 用于增删改(带参数)
     * 
     * @param sql
     *            sql语句
     * @param paramters
     *            sql语句
     * @return 影响行数
     * @throws SQLException
     */
    public int update(String sql, Object... paramters)
            throws SQLException {
    	init();
    	PreparedStatement preparedStatement = null;
        try {
        	preparedStatement = this.connection.prepareStatement(sql);
 
            for (int i = 0; i < paramters.length; i++) {
                preparedStatement.setObject(i + 1, paramters[i]);
            }
            return preparedStatement.executeUpdate();
        } catch (SQLException e) {
            throw new SQLException(e);
        } finally {
            free();
            preparedStatement.close();
        }
    }
    


doublecake 2015-04-13
  • 打赏
  • 举报
回复
引用 13 楼 Inhibitory 的回复:
Spring 默认只有抛出 RuntimeException才会回滚事务,其他的Exception,例如IOException,ArrayIndexOutOfBoundsException等都不会回滚事务,但是可以配置 rollbackFor,当制定的异常抛出是回滚事务。
@Inhibitory 就是抛的RuntimeException但是还是没有作用,我把我的基础Dao贴出来,你帮我看看呢
Inhibitory 2015-04-10
  • 打赏
  • 举报
回复
Spring 默认只有抛出 RuntimeException才会回滚事务,其他的Exception,例如IOException,ArrayIndexOutOfBoundsException等都不会回滚事务,但是可以配置 rollbackFor,当制定的异常抛出是回滚事务。
zengqw159 2015-04-10
  • 打赏
  • 举报
回复
需要把异常抛出来才能触发
doublecake 2015-04-10
  • 打赏
  • 举报
回复
引用 10 楼 u013762572 的回复:
首先要保证自己的数据库是否是支持回滚的(mysql 有中数据引擎是不支持回滚的)。。然后再看你的spring 。。。。。
@u013762572 我查了下我的mysql的引,是InnoDB,这种引擎支持事务。。。
microhex 2015-04-10
  • 打赏
  • 举报
回复
首先要保证自己的数据库是否是支持回滚的(mysql 有中数据引擎是不支持回滚的)。。然后再看你的spring 。。。。。
doublecake 2015-04-10
  • 打赏
  • 举报
回复
引用 7 楼 u012171905 的回复:
service中不要捕获异常,抛出给spring用于回滚事务
@u012171905 、、惨的不行。。我是没有做处理呀。。还是不回滚。。
doublecake 2015-04-10
  • 打赏
  • 举报
回复
引用 6 楼 lujiangui 的回复:
用这个@Transactional的话,在applicationContext.xml文件要增加<tx:annotation-driven transaction-manager="txManager"/> 配置,然后在需要事务的类上面添加@Transactional,在需要事务的方法类上面添加@Transactional(propagation = Propagation.NOT_SUPPORTED),括号内的propagation可以指定事务类型。这样就可以了,可能说得不太清楚,最后给你截个图吧
@lujiangui 惨的不行。。还是不回滚。。
Coder_D 2015-04-10
  • 打赏
  • 举报
回复
service中不要捕获异常,抛出给spring用于回滚事务
何事忧愁 2015-04-10
  • 打赏
  • 举报
回复
用这个@Transactional的话,在applicationContext.xml文件要增加<tx:annotation-driven transaction-manager="txManager"/> 配置,然后在需要事务的类上面添加@Transactional,在需要事务的方法类上面添加@Transactional(propagation = Propagation.NOT_SUPPORTED),括号内的propagation可以指定事务类型。这样就可以了,可能说得不太清楚,最后给你截个图吧
doublecake 2015-04-10
  • 打赏
  • 举报
回复
引用 1 楼 u013762572 的回复:
你声明@Transactional的呢????
@microhex 恩恩。。那请问。。怎么用呢?我这样做添加了@Transactional还是不起作用呀。。我在添加了注释的方法里面先执行了一句插入语句后,手动泡了一个错误,但是依然插入了数据库,,什么原因哦
doublecake 2015-04-10
  • 打赏
  • 举报
回复
引用 2 楼 lujiangui 的回复:
这个是声明式事务,还需要配置<tx:advice />和aop切面, 另外@Transactional是注解式的事务管理不是声明式事务管理
@lujiangui 恩恩。。那请问。。怎么用呢?我这样做添加了@Transactional还是不起作用呀。。我在添加了注释的方法里面先执行了一句插入语句后,手动泡了一个错误,但是依然插入了数据库,,什么原因哦
doublecake 2015-04-10
  • 打赏
  • 举报
回复
引用 2 楼 lujiangui 的回复:
这个是声明式事务,还需要配置<tx:advice />和aop切面, 另外@Transactional是注解式的事务管理不是声明式事务管理
恩恩。。那请问。。怎么用呢?我这样做添加了@Transactional还是不起作用呀。。
加载更多回复(2)

81,092

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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