求助,Spring Transaction rollbackFor 不起作用。

wrnoi 2017-12-21 10:43:45
近期在看Spring的事物管理,模拟情况是在同一个方法里面执行两次数据库更新操作,一次成功,一次失败 抛出SQLException,目的是想让这两次操作在同一个事物中,如果一个失败,两个操作都将会滚。
遇到的问题是,其中一条更新正常执行,一条更新由于抛出异常没有执行,个人感觉是Spring 的事物没有起作用。

下面是相关的Spring 配置 以及 Java代码
<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

<!-- scan the package and the sub package -->
<context:component-scan base-package="com.book" />

<!-- don't handle the static resource -->
<mvc:default-servlet-handler />

<!-- if you use annotation you must configure following setting -->
<mvc:annotation-driven />

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/book" />
<property name="username" value="xxx" />
<property name="password" value="xxx" />
</bean>

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

<!-- enable transaction annotation support -->
<tx:annotation-driven transaction-manager="txManager"/>

<!-- configure the InternalResourceViewResolver -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/" />
<!-- 后缀 -->
<property name="suffix" value=".jsp" />
</bean>
<bean id="com.book.service.BookLocalService" class="com.book.service.impl.BookLocalServiceImpl"></bean>
<bean id="com.book.dao.DBHelper" class="com.book.dao.DBHelper"></bean>

</beans>


------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Java 代码部分

import java.sql.PreparedStatement;
import java.sql.SQLException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.book.dao.DBHelper;
import com.book.service.BookLocalService;

public class BookLocalServiceImpl implements BookLocalService{

private String sql = "insert into book (name,price) values(?,?);";

@Transactional(propagation=Propagation.REQUIRED,readOnly=false,rollbackFor=SQLException.class)
@Override
public void addBook(String name, String price) throws SQLException {

PreparedStatement pst = _dbHelper.createPST(sql);
try {
pst.setString(1, "test");
pst.setString(2, "100");
pst.execute();
pst.setString(1, name);
pst.setString(2, price);
pst.execute();
}
catch (SQLException e) {
throw e ;
}
finally{
_dbHelper.closeConnection();
}
}

@Autowired
private DBHelper _dbHelper;
}

我在方法上面添加了@Transactional(propagation=Propagation.REQUIRED,readOnly=false,rollbackFor=SQLException.class)
理论上应该是当我添加非法数据导致throw SQLException的时候,两个数据库更新操作都应该回滚
当前的问题之前描述过,就是其中的一个数据库更新成功,另外一个失败,个人感觉Spring Transaction没有起作用。


谁能给分析下原因并给予解决方案?


万分感谢!
...全文
439 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
RockeyCui 2017-12-24
  • 打赏
  • 举报
回复
DBHelper 中的数据源用的是spring管理的数据源吗? 我看你并没有注入,是从代码中获取的?
wrnoi 2017-12-22
  • 打赏
  • 举报
回复
引用 2 楼 minemine0418 的回复:
确定走了catch块吗?
感谢回复,确定走了catch块,console已经抛出了SQLException。
wrnoi 2017-12-22
  • 打赏
  • 举报
回复
感谢回复,确定走了catch块,console已经抛出了SQLException。
wrnoi 2017-12-22
  • 打赏
  • 举报
回复
引用 5 楼 cxxiaoyuan 的回复:
不用进行try catch 只有抛出异常时rollbackfor才会起作用
首先感谢回复 我的代码中虽然添加了try catch 语句块,但是catch 内,我仍然做了 throw exception操作,我这里用try catch 之后又进行throw 只是为了用finally 去关闭连接。 并且 我把try catch移除之后也做了测试,仍然是不好用的。
  • 打赏
  • 举报
回复
不用进行try catch 只有抛出异常时rollbackfor才会起作用
minemine0418 2017-12-21
  • 打赏
  • 举报
回复
确定走了catch块吗?
wrnoi 2017-12-21
  • 打赏
  • 举报
回复
论坛不活跃?

81,090

社区成员

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

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