java Spring事务问题,以下代码会不会java 手动回滚事务

本帖子已过去太久远了,不再提供回复功能。关于spring嵌套事务不能回滚问题,求帮助 - ITeye问答
这个是第一个service代码
public class BaseService
{
private BaseDAOI
private TransactionTemplateUtils templateU
private UserService userServiceI
public void addUser(final Users user)
{
templateUtils.call(new ITransactionManager(){
@Override
public Users doInTransaction() throws CharException
{
dao.insert(&user_space.insertUsers&, user);
userServiceImpl.deleteUser(user.getLoginid());
public void setDao(BaseDAOImp dao)
{
this.dao =
}
public void setTemplateUtils(TransactionTemplateUtils templateUtils)
{
this.templateUtils = templateU
}
public void setUserServiceImpl(UserService userServiceImpl)
{
this.userServiceImpl = userServiceI
}
}
这个是第2个service代码在第一个service里面调用了,并抛出了一个自定义异常
public class UserService
{
private BaseDAOI
private TransactionTemplateUtils templateU
public void deleteUser(final String loginId)
{
templateUtils.call(new ITransactionManager(){
@Override
public Users doInTransaction() throws CharException
{
throw new CharException("aaaa");
}
});
}
public void setDao(BaseDAOImp dao)
{
this.dao =
}
public void setTemplateUtils(TransactionTemplateUtils templateUtils)
{
this.templateUtils = templateU
}
}
这个是自己写的一个事务管理类注入了TransactionTemplate中间的doInTransaction是自己写的一个接口回调
public class TransactionTemplateUtils
{
private TransactionTemplate transactionT
@SuppressWarnings( "unchecked" )
public boolean call(final ITransactionManager manager)
{
return (Boolean) transactionTemplate.execute(new TransactionCallback(){
@Override
public Object doInTransaction(TransactionStatus status)
{
O
try
{
result = manager.doInTransaction();
}
catch (CharException e)
{
throw new RuntimeException(e.getMsgContext(), e);
public void setTransactionTemplate(TransactionTemplate transactionTemplate)
{
this.transactionTemplate = transactionT
}
applicationContext.xml配置文件是这样定义的
&bean id="iBatisDaoSupport"
class="org.springframework.orm.ibatis.support.SqlMapClientDaoSupport"
abstract="true"&
&property name="sqlMapClientTemplate" ref="sqlMapClientTemplate" /&
&/bean&
&bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&
&property name="dataSource" ref="dataSource" /&
&/bean&
&bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"&
&property name="transactionManager" ref="txManager" /&
&/bean&
&bean id="templateUtils" class="net.sy599.yaolaiye.dao.impl.TransactionTemplateUtils"&
&property name="transactionTemplate" ref="transactionTemplate" /&
&/bean&
&bean id="baseService" class="net.sy599.yaolaiye.test.service.BaseService"&
&&& &property name="dao" ref="baseDAOImp"&&/property&
&&& &property name="templateUtils" ref="templateUtils"&&/property&
&&& &property name="userServiceImpl" ref="userService"&&/property&
&&& &/bean&
&&
&&& &bean id="userService" class="net.sy599.yaolaiye.test.service.UserService"&
&&& &property name="dao" ref="baseDAOImp"&&/property&
&&& &property name="templateUtils" ref="templateUtils"&
&&& &/property&
&&& &/bean&
&&
&&& &bean id="baseDAOImp" class="net.sy599.yaolaiye.test.dao.impl.BaseDAOImp"&
&&& &property name="sqlMapClient" ref="sqlMapClient"&&/property&
&&& &/bean&
请问为什么第二个service抛除了异常怎么数据库里面的数据不回滚啊。。。请帮忙解答下问题
目前还没有答案
已解决问题
未解决问题spring+mybatis注解式事务不回滚的原因分析@Transactional_Java教程_
spring+mybatis注解式事务不回滚的原因分析@Transactional
来源:人气:3414
在一个项目中发现sing的事务无法回滚。
DEBUG: org.mybatis.spring.SqlUtils - SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@49f9ce55] was not registered for synchronization because synchronization is not active
DEBUG: org.mybatis.spring.transaction.SpringManagedTransaction - JDBC Connection [ConnectionHandle{url=jdbc:postgresql://localhost/mypro, user=mypro, debugHandle=null, lastResetAgoInSec=92, lastUsedAgoInSec=92, creationTimeAgoInSec=92}] will not be managed by Spring
在网上找了好多,都没解决
我搜到的资料相关链接有:
/xunux/p/4388124.html
/topic/1123069
/blog/1611970
http://blog.csdn.net/will_awoke/article/details/ (最终在这里得到启发,问题解决)
其实,上面几个链接,都提到是包扫描的问题,要在包扫描的配置里加上
&context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/&
没错,真的是这个问题引起的。
起初,我已经加上了,但问题依旧,问题研究出在哪里呢?????:(&:(&:((伤心啊!!!)
后来找到这里:http://blog.csdn.net/will_awoke/article/details/,里面有讲到:
Spring容器优先加载由ServletContextListener(对应Context.)产生的父容器,而SpringMVC(对应mvc_dispatcher_servlet.xml)产生的是子容器。子容器Controller进行扫描装配时装配的@Service注解的实例是没有经过事务加强处理,即没有事务处理能力的Service,而父容器进行初始化的Service是保证事务的增强处理能力的。如果不在子容器中将Service exclude掉,此时得到的将是原样的无事务处理能力的Service,因为在多上下文的情况下,如果同一个bean被定义两次,后面一个优先。
好了,问题关键是父容器和子容器的事了。
我细心检查项目中的web.xml配置
&context-param&
&param-name&contextConfigLocation&/param-name&
&param-value&
/WEB-INF/spring/root-context.xml
classpath:/applicationContext-*.xml
classpath:/applicationContext-mypro.xml
classpath:/applicationContext-core.xml
&/param-value&
&/context-param&
&filter-name&encodingFilter&/filter-name&
&filter-class&org.springframework.web.filter.CharacterEncodingFilter&/filter-class&
&init-param&
&param-name&encoding&/param-name&
&param-value&UTF-8&/param-value&
&/init-param&
&init-param&
&param-name&forceEncoding&/param-name&
&param-value&true&/param-value&
&/init-param&
&filter-mapping&
&filter-name&encodingFilter&/filter-name&
&url-pattern&/*&/url-pattern&
&/filter-mapping&
&listener&
&listener-class&org.springframework.web.context.ContextLoaderListener&/listener-class& (说明:这个是产生父容器的,这与上面context-param,contextConfigLocation有关系)
&/listener&
&servlet-name&appServlet&/servlet-name&
&servlet-class&org.springframework.web.servlet.DispatcherServlet&/servlet-class&
&init-param&
&param-name&contextConfigLocation&/param-name&
&param-value&/WEB-INF/spring/appServlet/servlet-context.xml&/param-value&
(说明:这个是产生子容器的,即springmvc的ContextApplication是子容器)
&/init-param&
&load-on-startup&1&/load-on-startup&
&/servlet&
&servlet-mapping&
&servlet-name&appServlet&/servlet-name&
&url-pattern&/&/url-pattern&
&/servlet-mapping&
我的项目是maven构建,项目分为mypro-web,和mypro-core两个模块,其中mypro-web依赖mypro-core模块,mypro-core最终打成jar包,放在mypro-web的lib下面。
原因就是我的mypro-web和mypro-core中都有applicationContext-mypro.xml这个配置文件(这两个文件里面的东西是一样的),这个文件里就配了事务相关的东西。
&!-- 事务管理器配置,单数据源事务 --&
&bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" &
&property name="dataSource" ref="dataSource" /&
&!-- 支持注解式事务 --&
&tx:annotation-driven transaction-manager="transactionManager" /&
所以,我猜这导致spring在构建事务声明时,出问题了,
把mypro-web中的applicationContext-mypro.xml文件删除,问题解决!!!
优质网站模板spring 事务回滚
1、遇到的问题
  当我们一个方法里面有多个数据库保存操作的时候,中间的数据库操作发生的错误。伪代码如下:
public method() {
Dao1.save(Person1);
Dao1.save(Person2);
Dao1.save(Person2);//假如这句发生了错误,前面的两个对象会被保存到数据库中
Dao1.save(Person2);
  期待的情况:发生错误之前的所有数据库保存操作都回滚,即不保存
  正常情况:前面的数据库操作会被执行,而发生数据库操作错误开始及之后的所有的数据保存操作都将失败。这样子应该都不是我们要的结果吧。
  当遇到这种情况,我们就可以使用Spring的事务解决这个问题。
2、异常的一些基本知识
1) 异常的架构
  异常的继承结构:Throwable为基类,Error和Exception继承Throwable,RuntimeException和IOException等继承Exception。Error和RuntimeException及其子类成为未检查异常(unchecked),其它异常成为已检查异常(checked)。
2)Error异常
  Error表示程序在运行期间出现了十分严重、不可恢复的错误,在这种情况下应用程序只能中止运行,例如JAVA 虚拟机出现错误。Error是一种unchecked Exception,编译器不会检查Error是否被处理,在程序中不用捕获Error类型的异常。一般情况下,在程序中也不应该抛出Error类型的异常。
3)RuntimeException异常
  Exception异常包括RuntimeException异常和其他非RuntimeException的异常。
  RuntimeException 是一种Unchecked Exception,即表示编译器不会检查程序是否对RuntimeException作了处理,在程序中不必捕获RuntimException类型的异常,也不必在方法体声明抛出 RuntimeException类。RuntimeException发生的时候,表示程序中出现了编程错误,所以应该找出错误修改程序,而不是去捕获RuntimeException。
4)Checked Exception异常
  Checked Exception异常,这也是在编程中使用最多的Exception,所有继承自Exception并且不是RuntimeException的异常都是checked Exception,上图中的IOException和ClassNotFoundException。JAVA 语言规定必须对checked Exception作处理,编译器会对此作检查,要么在方法体中声明抛出checked Exception,要么使用catch语句捕获checked Exception进行处理,不然不能通过编译。
  这里使用的事务配置如下:
&!-- Jpa 事务配置 --&
&bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"&
&property name="entityManagerFactory" ref="entityManagerFactory"/&
&!-- 开启注解事务 --&
&tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" /&
  在spring的配置文件中,如果数据源的defaultAutoCommit设置为True了,那么方法中如果自己捕获了异常,事务是不会回滚的,如果没有自己捕获异常则事务会回滚,如下例
比如配置文件里有这么条记录
&bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"&
&property name="xxx" value="xxx"/&
&property name="xxx" value="xxx"/&
&property name="defaultAutoCommit" value="true" /&
  可能你会发现你并没有配置这个参数,是不是他就不会自动提交呢?答案是不是的,我这里是使用了com.alibaba.druid.pool.DruidDataSource作为数据库连接池,默认的defaultAutoCommit就是true,可以看下面的源码
  那么现在有两个情况
  情况1:如果没有在程序中手动捕获异常
@Transactional(rollbackOn = { Exception.class })
public void test() throws Exception {
doDbStuff1();
doDbStuff2();//假如这个操作数据库的方法会抛出异常,现在方法doDbStuff1()对数据库的操作
  情况2:如果在程序中自己捕获了异常
@Transactional(rollbackOn = { Exception.class })
public void test() {
doDbStuff1();
doDbStuff2();//假如这个操作数据库的方法会抛出异常,现在方法doDbStuff1()对数据库的操作 不会回滚。
} catch (Exception e) {
e.printStackTrace();
  现在如果我们需要手动捕获异常,并且也希望抛异常的时候能回滚肿么办呢?
  下面这样写就好了,手动回滚事务:
@Transactional(rollbackOn = { Exception.class })
public void test() {
doDbStuff1();
doDbStuff2();
} catch (Exception e) {
e.printStackTrace();
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//就是这一句了,加上之后,如果doDbStuff2()抛了异常,
//doDbStuff1()是会回滚的
&& 感谢您的阅读!谢谢!
欢迎转载:
推荐:    

我要回帖

更多关于 java action事务回滚 的文章

 

随机推荐